Django - 视图
- 作用
- 接收 Web 请求并返回 web 响应
- 本质
- 就是一个 Python 函数,被定义在 views.py 文件中
- 响应
- 可以是一个网页的 HTML 内容、一个重定向、数据、一个 404 错误等等
- 过程
指定根级 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
概述:
- 服务器收到 http 协议的请求后,会根据报文创建 HTTPRequest 对象
- 视图函数的第一个参数时 HTTPRequest 对象
属性
path
:字符串类型,表示请求的完整路径,不包含域名和端口method
:字符串类型,表示使用的 HTTP 方法,常用的包括 GET、POSTencoding
:字符串类型,表示提交数据的编码方式- 如果为 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("收到用户信息")
- 使用表单提交,目前需要在 settings.py 中注释掉 csrf
概述: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)
:设置 cookiedalete_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
使用 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: