Django-视图
概述
- 作用
- 接收Web请求并返回web响应
- 本质
- 就是一个Python函数,被定义在views.py文件中
- 响应
- 可以是一个网页的HTML内容、一个重定向、数据、一个404错误等等
- 过程
URLconf
-
指定根级url配置文件
settings.py
文件中的ROOT_URLCONF
-
指定子路由
- 在应用下创建子路由urls.py文件
- 在主路由中引用
1
2
3
4
5urlpatterns = [
url(r'^admin/', admin.site.urls),
# namespace表示命名空间
url(r'^', include('myApp.urls', namespace="sunck")),
]
-
urlpatterns
- 一个
RegexURLResolver
实例的列表 url()
参数- 正则表达式
- 视图函数
- 名称
1
url(r'^$', views.index, name="index"),
- 一个
视图函数
-
定义视图
- **本质:**一个函数
- 视图参数:
-
一个
HTTPRequest
对象 -
通过正则表达式组获取的位置参数
如果路由带有正则表达式组,在定义视图函数时,要对应用形参接收
-
通过正则表达式组获取的关键字参数
-
- **位置:**应用目录下的
views.py
文件中 - **说明:**如果处理的功能过多,可以将视图定义在不同的py文件中
-
错误视图
-
404
- 在
templates
目录下创建名为404.html
文件1
2
3
4
5
6
7
8
9
10
11
12<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>公益404</title>
</head>
<body>
<script src="//qzonestyle.gtimg.cn/qzone/hybrid/app/404/search_children.js"
charset="utf-8" homePageUrl="/" homePageName="返回首页">
</script>
</body>
</html> - 修改
settions.py
文件1
2
3DEBUG = False
ALLOWED_HOSTS = ["*",]当为True时永远不会使用404页面
- 在
-
500
- 在视图代码中出现运行时错误
-
400
- 错误来自客户端的操作
- 当用户进行的操作在安全方面可以的时候,例如篡改会话cookie
-
HttpRequest对象
-
概述:
- 服务器收到http协议的请求后,会根据报文创建HTTPRequest对象
- 视图函数的第一个参数时HTTPRequest对象
-
属性
- **
path
:**字符串类型,表示请求的完整路径,不包含域名和端口 - **
method
:**字符串类型,表示使用的HTTP方法,常用的包括GET、POST - **
encoding
:**字符串类型,表示提交数据的编码方式- 如果为None则表示使用浏览器默认的设置,一般为utf-8
- 这个属性是可写的,可以通过修改它来修改方法表单数据的编码
- **
GET
:**一个类似字典的对象,包含了get请求方式的所有参数 - **
POST
:**一个类似字典的对象,包含了POST请求方式的所有参数 - **
FILES
:**一个类似字典的对象,包含的是所有的上传文件 - **
COOKIES
:**一个标准的python字典,包含所有的cookie,键和值都是字符串 - **
session
:**一个即可读又可写的类似于字典的对象,表示当前会话,只有Django启动会话才支持session属性
- **
-
方法
- **
is_ajax()
:**如果请求是通过XMLHttpRequest
发起的,返回True
- **
-
QueryDict对象
- request对象的属性GET、POST都是QueryDict类型的对象
- 与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
get()
:- 功能:根据键获取值
- 注意:只能获取一个值;如果一个键同时用过多个值,获取最后一个值
- **
getlist()
:**将键对应的值以列表的形式返回,可以获取一个键的多个值
-
GET属性
- 127.0.0.1:8000/get1?a=1&b=2&c=3
1
2
3
4
5def get1(request):
a = request.GET.get("a")
b = request.GET.get("b")
c = request.GET.get("c")
return HttpResponse(a + b + c) - 127.0.0.1:8000/get2?a=1&a=2&c=3
1
2
3
4def get2(request):
alist = request.GET.getlist("a")
c = request.GET.get("c")
return HttpResponse(alist[0] + alist[1] + c)
- 127.0.0.1:8000/get1?a=1&b=2&c=3
-
POST属性
-
使用表单提交,目前需要在settings.py中注释掉csrf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<form action="/login/" method="POST">
{# {% csrf_token %}#}
账号:<input type="text" value="" name="username"/><br/>
密码:<input type="password" value="" name="passwd"/><br/>
爱好:<input type="checkbox" value="power" name="hobby"/>权利
<input type="checkbox" value="money" name="hobby"/>金钱
<input type="checkbox" value="knowledge" name="hobby"/>知识<br/>
<input type="submit" value="登陆"/>
</form>
</body>
</html>1
2
3
4
5
6
7
8
9def login(request):
if request.method == "GET":
return render(request, "myApp/login.html")
else:
username = request.POST.get("username")
passwd = request.POST.get("passwd")
hobbys = request.POST.getlist("hobby")
print(username, passwd, hobbys)
return HttpResponse("收到用户信息")
-
HttpResponse对象
-
**概述:**HttpRequest对象是由Django自动创建,HTTPResponse对象由程序员创建
-
用法
- 调用模板:
render()
函数- 原型:
render(request, template_name, context=None)
- 说明:结合一个给定模板和一个给定的上下文字典,并返回一个渲染后的HTTPResponse对象
- 参数:
request
:用于生成response
template_name
:要使用的模板名称context
:传递个模板的数据
- 应用:
return render(request, "myApp/login.html")
- 原型:
- 直接返回数据:
return HttpResponse("收到用户信息")
- 调用模板:
-
属性
- **
content
:**表示返回的内容,字符串类型 - **
charset
:**表示response采用的编码字符集,字符串类型 - **
status_code
:**响应的HTTP状态码 - **
content_type
:**指定输出的MIME类型1
2
3
4
5
6
7
8def restest(request):
response = HttpResponse()
response.content = "sunck is a nice man"
response.charset = "utf-8"
response.status_code = 200
response.content_type = "application/json"
return response
- **
-
方法
- **
init
:**使用页面内容实例化HTTPResonance对象 write(content)
:以文本的方式写- **
flush()
:**以文件的方式输出缓冲区 - **
set_cookie(key, value, max_age=None, expires=None)
:**设置cookie - **
dalete_cookie(key)
:**删除指定cookie,如果删除的cookie不存在就当什么都没发生
- **
-
子类
HttpResponseRedirect
- 重定向,服务端跳转
1
2
3def index1(request):
# 路由重定向
return HttpResponseRedirect('/') - 简写方式:
redirect()
- 原型:redirect(to, *args, **kwargs)
- 实现:
1
2
3
4def index1(request):
# 路由重定向
# return HttpResponseRedirect('/')
return redirect("/") - 注意:to推荐使用反向解析
- 重定向,服务端跳转
-
子类
JsonResponse
- 返回Json数据,一般用于ajax异步请求
- JsonResponse的对象的Content-Type值默认为application/json
状态保持
-
概述:
- http协议是无状态,每次请求都是一次新的请求,不会记得之前的通信状态
- 客户端与服务端的一次通信就是一次会话
- 实现状态保持的方式:在客户端或服务端存储会话的有关数据
- 存储方式:
cookie
session
:会话一般指的是session对象
- 使用cookie,所有的数据存储在客户端,在客户端不要存储敏感信息
- 推荐使用session方式,所有的数据存储在服务端,在客户端cookie中存储session_id
- 状态保持的目的:在一段时间内跟踪请求者的状态,可以实现跨页面的访问请求者的数据
- 注意:不同的请求者之间不会共享数据,与请求者一一对应的
-
启用session:
settings.py
文件- INSTALLED_APPS
1
'django.contrib.sessions',
- MIDDLEWARE
1
'django.contrib.sessions.middleware.SessionMiddleware',
- INSTALLED_APPS
-
使用session
- 启用会话后,每个HTTPRequest对象将具有一个session属性,它是一个类似字典的对象
- 取值:
get(key, default=None)
- 根据键获取会话的值
- 删除:
clear()
:清除所有会话flush()
:删除当前会话数据,并且删除cookiedel request.session['键名']
:删除一个会话
-
示例
1
2
3
4
5# 状态保持
url(r'^home/$', views.home),
url(r'^cart/$', views.cart),
url(r'^login/$', views.login),
url(r'^quit/$', views.quit),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
44from django.shortcuts import render, redirect
def home(request):
username = request.session.get("username", default="未登录")
return render(request, 'myApp/home.html', {"username": username})
def cart(request):
username = request.session.get("username", default="未登录")
return render(request, 'myApp/cart.html', {"username": username})
def login(request):
if request.method == "GET":
fromPath = request.GET.get("from")
return render(request, 'myApp/login.html', {"from": fromPath})
else:
username = request.POST.get("username")
passwd = request.POST.get("passwd")
url = request.GET.get("from")
if username == "sunck" and passwd == "123qweasdzxc":
# 登陆验证成功
# 将用户名存储到session中
request.session["username"] = username
url = "/" + url + "/"
response = redirect(url)
# 设置cookie
response.set_cookie("token", "123456")
return response
else:
# 登陆验证失败
url = "/login/?from=" + url
return redirect(url)
from django.contrib.auth import logout
def quit(request):
logout(request)
return redirect('/home/')1
2
3
4
5
6
7
8
9
10
11
12
<html lang="en">
<head>
<meta charset="UTF-8">
<title>home</title>
</head>
<body>
<h1>home欢迎:{{ username }}</h1>
<a href="/login/?from=home">登陆</a>
<a href="/quit/">退出</a>
</body>
</html>1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<form action="/login/?from={{ from }}" method="POST">
账号:<input type="text" value="" name="username" /><br/>
密码:<input type="password" value="" name="passwd" /><br/>
<input type="submit" value="登陆" />
</form>
</body>
</html> -
过期时间
set_expiry(value)
:设置会话的过期时间- 如果没有指定,则默认两个星期后过期
- 如果value是一个整数,会话会在value秒没有活动后过期
- 如果value是timedelta对象,会话将在当前时间加上这个指定的日期/时间后过期
- 如果value是0,那么用户会话的cookie将在用户的浏览器关闭时过期
- 如果value是None,那么会话永不过期
1
2
3
4
5
6request.session["username"] = username
url = "/" + url +"/"
response = redirect(url)
# 设置过期时间
request.session.set_expiry(10)
-
存储session
-
基于数据库的会话:
- 默认的会话存储方式
1
SESSION_ENGINE='django.contrib.sessions.backends.db'
- 默认的会话存储方式
-
基于缓存的会话
- 只存在本地内存中,如果丢失则不能找回,比数据库的方式读写更快
1
SESSION_ENGINE='django.contrib.sessions.backends.cache'
- 只存在本地内存中,如果丢失则不能找回,比数据库的方式读写更快
-
缓存和数据库同时使用
- 优先从本地缓存中获取,如果没有则从数据库中获取
1
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
- 优先从本地缓存中获取,如果没有则从数据库中获取
-
-
使用redis缓存session
- 安装django-redis-session:
pip install django-redis-sessions
- 配置:在
settings.py
最后边添加以上代码1
2
3
4
5
6SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'
- 安装django-redis-session: