Django web开发

一、使用 Django 模板的基本过程:

1.django-admin.py startproject projectname

2.在项目目录中创建一个应用 django-admin.py startapp appname

3.在项目目录中的 settings.py 配置文件中的 INSTALLED_APPS 中添加创建的应用(加 ,)

4.在 APP 目录中创建默认的模板(html)目录 templates,html文件保存在这里,例如:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content= "text/html;charset=UTF-8">
<title></title>
</head>
<body>
<h1>hello!{{uname}}</h1> // uname 外应该是两个大括号
</body>
</html>

5.然后编辑项目目录中的 urls.py 文件,添加 url(r’^$,def)

分别对应url的正则表达式和对应的处理函数 ,例如:

1
url(r'^index/$,'blog.views.index')

就是访问 url/index/ 时调用 views.index 处理函数

6.编辑处理函数,例如编辑 APP blog中的 views.py:

1
2
3
4
5
6
7
8
9
10
11
from django.template import loader,Context
from django.http import HttpResponse

def index(request):
t = loader.get_template('index.html')
# loader 中的 get_template 方法载入对应的模版文件
c = Context{{'uname':'simon'}}
# Context 对象将模板与对象建立动态联系
html = t.render(c)
return html
# html 是将模板动态渲染后返回的html字符串

也可以直接使用 Template 类:

1
2
3
4
5
6
7
8
from django import Template
from django.http import HttpResponse

def index1(request):
t = Template('<h1>hello {{uname}}</h1>')
# Template 构造方法直接传入模板html
c = Context({'uname':'simon'})
return HttpResponse(t.render(c))

更直接的方法:

1
2
3
4
5
from django.shortcuts import render_to_response

def index2(request):
return render_to_response('index.html',{'uname':'simon'})
# 直接返回一个 HttpResponse 对象

7.python manage.py runserver 启动开发服务器调试(8000 端口),访问的url一定要符合定义的正则表达式。

二、django 模板标签

// 这里 百分号的 token 有问题,就不写了。。。

三、django 使用数据库

1. 基本配置:

1). 配置 settings.py 中的 DATABESES 项目

2). 配置APP文件夹中的 models.py 文件,以建立数据库中的表:

1
2
3
4
5
6
7
8
from django.db import models

class Employee(models.Model):
name = models.CharField(max_length=20)

def __unicode__(self):
return self.name
# unicode 方法返回的是类默认的表示方法,类似于Java中的 toString

3). 数据库同步:python manage.py syncdb 自动建立 APP_employee 表,表中除了有字段 name ,还有默认添加的主键 id 字段。

2. models 数据操作

1). 数据添加

1
2
3
4
5
6
7
8
9
10
from blog.models import Employee

emp = Employee()
emp.name = 'Alen' # 方式1
emp.save()

emp = Employee(name='Tom') # 方式2,比较常用,直接在类的构造字段输入数据
emp.save()

Employee.objects.create(name='Max') # 直接写入,通过类管理器

查询一下:

1
2
use csvt;     // 选择 csvt 数据库
select * from blog_employee; // 查询动作

2). 数据查询

1
2
3

emps = Employee.objects.all()
# 返回的 emps 是一个包含所有字段的列表(都是 object,表示形式和类的 __unicode__ 方法有关),可以通过 类似 emps[0].id 语句查询具体值。

3). 使用

1
2
3
4
5
6
from blog.models impost Employee
from django.shortcuts import render_to_response

def index(request):
emps = Employee.objects.all()
return render_to_response('index.html',{'emps':emps})

3. 关系模型

1). 多对一关系模型:

在同一个 models 下设置多个class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.db import models

class Entry(models.Model):
name = models.CharField(max_length=30)

def __unicode__(self):
return self.name

class Blog(models.Model):
name = models.CharField(max_length=30)
entry = models.ForeignKey(Entry)
# 利用 ForeignKey 形成多对一关系模型,外键传入类名
# 一个 Entry 里面可以有多个 Blog
def __unicode__(self):
return self.name
1
2
3
4
5
from blog.models import Entry, Blog
entry1 = Entry.objects.create(name='alen')
entry2 = Entry.objects.create(name='max')
entry3 = Entry.objects.create(name='carl')
blog1 = Blog.objects.create(name='alen_blog1',entry=entry1)

4. admin 后台管理数据库

1). 配置 settings.py: 在INSTALLED_APPS 字段中添加 ‘django.contrib.admin’,

2). 在 urls.py 中完成配置,开头加入:

1
2
from django.contrib import admin
admin.autodiscover()

3). models.py 文件中创建表

1
2
3
4
5
6
7
8
9
10
11
12
13
14

from django.db import models

sex_choices = (
('f','famale')
('m','male')
) # 定义一个选择元组

class User(models.Model):
name = models.CharField(max_length=20)
sex = models.CharField(max_length=1, choices=sex_choices)

def __unicode__(self):
return self.name

4). 在APP文件夹中创建 admin.py:

1
2
3
4
from django.contrib import admin
from blog.models import User

admin.site.register(User) #注册一下

5).创建完成之后,在命令行提示下建立一个管理员账户,进入url/admin/ 就进入了后台管理界面,可以添加 User (会同时在数据库中添加记录),进行认证管理等可视化操作。

四、Django 表单

1. 表单的基本使用

1). 基本配置:建立APP,配置settings.py,url.py 处理函数为 blog/views

views
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django import forms
from django.http import HttpResponse
from django.shortcuts import render_to_response

class UserForm(forms.Form):
name = forms.CharField()

def register(request):
if request.method == 'POST': # 如果表单进行了提交
from = UserForm(request.POST)
if form.is_valid(): # 如果提交的数据有效
print form.cleaned_data # 利用 form 中的方法获取数据
return HttpResponse('ok')
else:
form = UserForm()
return render_to_response('register.html',{'form':form})

2).配置模版文件 register.html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<from method="post">
{{from}}
<input type="submit" value="ok" />
</form>
</body>
</html>

3). 上传处理遇到 CSRF 错误:

配置 settings.py 中的 MIDDLEWARE_CLASSES 对应的 CSRF 项注销掉

2. form 字段

以视图处理方法 blog.views.regist 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from django.shortcuts import render_to_response
from django import forms
from django import HttpResponse

class UserForm(forms.Form):
username = forms.CharField()
headImg = forms.FileField() # 上传文件对象

def regist(request):
if request.method == 'POST':
uf = UserForm(request.POST,requset.FILES)
if uf.is_valid():
print uf.cleaned_data['username']
print uf.cleaded_data['headImg']
#print uf.cleaded_data['headImg'].name 文件名
#print uf.cleaded_data['headImg'].size 文件大小 一些方法
fp = file('/uploadfile/'+uf.cleaded_data['headImg'].name.'wb')
# 打开某个文件以存储
s = uf.cleaned_data['headImg'].read()
# 把上传文件的内容独取出来
fp.write(s)
fp.close()
return HttpResponse('ok')
else:
uf = UserForm()

return render_to_response('regist.html',{})

有关 上传文件对象的详细内容,查阅 Django 文档 HttpRequest.FILES,UploadedFile.

1
2
3
4
5
6
<form method="POST" enctype="multipart/form-data">    
<!--enctype段是为了完成文件上传所加-->
{{uf.as_p}}
<!-- as_p 表示把 form 表单在前端页面渲染成p标签的形式,类似的还有 as_ul/as_table 等-->
<input type="submit" value="ok"/>
</form>

3. 利用后台管理完成文件上传

打开 settings.py INSTALLED_APPS 中的 django.contrib.admin, 配置数据库:

1
2
3
4
5
6
7
8
from django.db import models

class User(models.Model):
username = models.CharField(max_length=30)
headImg = models.FileField(upload_to='./upload/')

def __unicode__(self):
return self.username

配置 url.py :

1
2
3
4
5
6
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
url(r'^admin/',include(admin.site.urls)),
)

python manage.py syncdb 同步数据库

在 blog 文件夹下创建 admin.py 文件:

1
2
3
4
from django.contrib import admin
from blog.models import UserForm

admin.site.register(User)

同时,配置 settings.py 中的 MEDIA_ROOT 字段还可以设置文件上传的具体路径,此时数据库保存的只是路径。

五、Django 会话

通过会话功能实现页面间信息的传递弥补 HTTP 协议的不足:
cookie 本身保存在客户端,通过 HttpResponse 对象进行传递。

HttpResponse.set_cookie(key,value=””,max_age=None,expires=None,path=’/‘,domain=None,secure=None,httponly=False)

Request 对象的 .COOKIE 可以直接把接收到的 cookies 当做字典来使用

max_age: 有效秒数。

建立 APP online。配置 url.py :

1
2
3
4
url(r'^regist/$','online.views.regist'),
url(r'^login/$','online.views.login'),
url(r'^index/$’,‘online.views.index),
url(r'^logout/$’,‘online.views.logout),

配置下 online/models.py 建立 有 username,password 属性的 User 类。

views.py :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from django import forms
from django.http import HttpResponse
from django.shortcuts import render_to_response
from models import User

class UserForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)

def regist(request):
if request.method == 'POST':
uf =UserForm(request.POST)
if uf.is_valid():
username = uf.cleaned_data['username']
password = uf.cleaned_data['password']
User.objects.create(username=username,password=password)
return HttpResponseRedirect('/login/') # 跳转url
else:
uf = UserForm()
return render_to_response('regist.html',{'uf':uf})

def login(request):
if request.method == 'POST':
uf =UserForm(request.POST)
if uf.is_valid():
username = uf.cleaned_data['username']
password = uf.cleaned_data['password']
users = User.objects.filter(username__exact=username,password__exact=password)
if users:
response = HttpResponseRedirect('/index/') # 跳转url
response.set_cookie('username',username,3600)
# 以字典方式传递
return response
else:
return HttpResponseRedirect('/login/') # 登陆不成功
else:
uf = UserForm()
return render_to_response('login.html',{'uf':uf})

def index(request):
username = req.COOKIE.get('username','')
#return HttpResponse('hello %s' % username)
return render_to_response('index.html',{'username':username})

# 在 index.html 中加入 logout 的链接 调用 logout 方法

def logout(request):
response = HttpResponse('logout')
response.delete_cookie('username')
return response

2. Session

Session 与 Cookie 不同之处在于把信息放在服务器端提高安全性,需要数据库支持。

HttpRequest.session 是一个类似于字典的对象,用字典有关的方法进行操作。

需要打开 settings.py 中的 MIDDLEWARE_CLASSES.django.contrib.sessions.middleware.SessionMiddleware 中间件,以及 APPS 中的 django.contrib.sessions (默认打开)

url.py 中与上面配置相同

views.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

from django import form
from django.shortcuts import render_to_response
from django.http import HttpResponse,HttpResponseRedirect

class UserForm(forms.Form):
username = forms.CharField()

def login(request):
if request.method == "POST":
uf = UserForm(request.POST)
uf.is_valid():
username = uf.cleaned_data['username']
request.session['username'] = username
#相关数据保存在 django_session 表中
return HttpResponseRedirect('/index')

else:
uf = UserForm()
return render_to_response('login.html',{'uf':uf})

def index(request):
username = request.session.get('username','anybody')
return HttpResponse('welcome %' % username)

def logout(request):
del request.sesson['username']
return HttpResponse('logout!')

数据库本身会默认创建 django.sessions 表,信息以键值对的形式加密保存,在客户端的 cookie 中会保存有关键的字符串,服务器会根据键来在数据库中查找值。

六、Django 用户管理

使用 Django 自身集成的用户管理系统,需要数据库支持以及打开 APPS 中的 django.contrib.auth 以及 django.contrib.admin

只要进行了 url.py 中 admin 相关配置,就可以在后台进行图形化的 User 管理。

使用代码进行用户管理:

1
2
3
4
5
6
7
from django.contrib.auth.models import User

User.objects.all() # 显示所有用户
User.objects.create_user(username='ben',passwd='111',email='abc@a.com')
ben.is_staff
ben.is_staff = True # 设置相关属性
ben.save() # 保存