Django视图
视图定义
一个视图函数,简称视图,就是
应用
中views.py
文件中的函数,它接受 Web 请求并且返回 Web 响应。视图必须返回一个
HttpResponse对象
或子对象
(JsonResponse
HttpResponseRedirect
)作为响应视图负责接受Web请求
HttpRequest
,进行逻辑处理,返回Web响应HttpResponse
给请求者视图层中有两个重要的对象:**请求对象(request)**与 **响应对象(
HttpResponse
)**。处理过程:
视图使用
在项目的
urls.py
文件定位应用的urls.py
1
2
3
4
5
6
7
8from django.contrib import admin # 默认配置
from django.urls import path, include # 导入include
urlpatterns = [
path('admin/', admin.site.urls), # 默认配置
path('', include('book.urls')) # 配置应用的urls
]在应用的
views.py
中定义视图函数1
2
3
4
5
6
7
8
9
10
11
12from django.http import HttpResponse
# 这里定义index视图函数 向页面传递完成请求
def index(request): # request为请求的数据
print('测OwO试')
return HttpResponse('OK')
''' 也可以通过render映射到templates指定html中 例如:'''
from django.shortcuts import render
def index(request):
data = {'text':'测OwO试'}
return render(request,'book/index.html',data)在应用的
urls.py
中配置视图函数1
2
3
4
5
6
7
8from django.urls import path
from book.views import index # 从你的应用.views中导入视图函数
# 固定写法 urlpatterns = [...]
urlpatterns = [
# 通过path('地址', 视图函数) 导入
path('index/', index),
]
HttpRequest对象
Django 使用请求和响应对象通过系统传递状态。
当请求一个页面时,Django 创建一个HttpRequest
包含请求元数据的对象。然后 Django 加载适当的视图,将 传递HttpRequest
给视图函数的第一个参数。每个视图负责返回一个HttpResponse
对象。
请求体
请求体数据格式不固定,可以是表单类型字符串 或 JSON字符串 或 XML字符串,要区别对待。
可以发送请求体数据的请求方式有POST、PUT、PATCH、DELETE。
Django默认开启了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制,方法为在项目中的settings.py文件中注释掉CSRF中间件
QueryDict
数据类型是 QueryDict,一个类似于字典的对象,包含 HTTP GET 的所有参数。
GET
有相同的键,就把所有的值放到对应的列表里。
取值格式:对象.方法。
**get()**:返回字符串,如果该键对应有多个值,取出该键的最后一个值。
不存在返回None
,可以设置默认值进行后续处理
1 | get('键', 默认值) |
getlist():根据键获取值,值以列表返回,可以获取指定键的所有值
不存在返回空列表
,可以设置默认值进行后续处理
1 | getlist('键', 默认值) |
POST
常用于 form 表单,form 表单里的标签 name 属性对应参数的键,value 属性对应参数的值。
取值格式: 对象.方法。
**get()**:返回字符串,如果该键对应有多个值,取出该键的最后一个值。
1 | request.POST.get() |
Query String
获取请求路径中的查询字符串参数,可以通过request.GET属性获取,返回QueryDict对象。
1 | # 语法 request.GET.get/getlist(xxx) |
HttpRequest常用对象
body
数据类型是二进制字节流,是原生请求体里的参数内容,在 HTTP 中用于 POST,因为 GET 没有请求体,返回bytes类型。
在 HTTP 中不常用,而在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML、Json 等。
1 | xx = request.body |
path
获取 URL 中的路径部分,数据类型是字符串
1 | xx = request.path |
method
表示请求使用的HTTP方法,数据类型是字符串,且结果为大写(常用值包括:’GET’、’POST’ )
1 | xx = request.method |
encoding
一个字符串,表示提交的数据的编码方式。
如果为None则表示使用浏览器的默认设置,一般为utf-8
。
这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
1 | xx = request.encoding |
FILES
一个类似于字典的对象,包含上传的文件。
1 | xx = request.FILES |
COOKIES
一个标准的Python字典,包含所有的cookie,键和值都为字符串。
1 | xx = request.COOKIES |
session
一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见”状态保持”。
1 | xx = request.session |
From Data 表单类型
前端发送的表单类型的请求体数据,可以通过request.POST属性获取,返回 QueryDict对象。
1 | # 语法 request.POST.get/getlist(xxx) |
Non-Form Data 非表单类型
非表单类型的请求体数据,Django无法自动解析,可以通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。request.body返回bytes类型(二进制格式)。
1 | # 如数据 : {'a': 1, 'b': 2} |
路径转换器
系统为我们提供了一些路由转换器位置在django.urls.converters.py
1 | DEFAULT_CONVERTERS = { |
我们可以通过以下形式来验证数据的类型
1 | path('<int:id>/<slug:username>/', login), |
自定义转换器
如果默认的路由转换器无法满足需求时,我们就需要 自定义路由转换器。
在任意可以被导入的python文件中,都可以自定义路由转换器。
我们这里给他划分为5步:
- 创建一个converters.py,在文件中定义一个类。
- 在类中定义一个属性regex,这个属性是用来保存url转换器规则的正则表达式。
- 实现to_python(self,value)方法,这个方法是先将url中的值转换,再传给视图函数的。
- 实现to_url(self,value)方法,这个方法是在做url反转时,将传进来的参数转换后拼接成一个正确的url。
- 将定义好的转换器,注册到django中。
示例<三步曲> 定义一个为匹配手机号的自定义转换器 :
- 第一步 项目根目录下,新建
converters.py
文件,用于自定义路由转换器
1 | """自定义路由转换器:匹配手机号""" |
- 第二步 在
总路由
中注册自定义路由转换器
1 | from django.urls import register_converter |
- 第三步 使用自定义路由转换器
1 | # 子路由使用 |
请求头
可以通过 request.META
属性获取请求头headers中的数据,request.META为字典类型。
包含所有可用 HTTP 请求头的字典。可用的请求头取决于客户端和服务器,
常见的请求头 | 说明 |
---|---|
CONTENT_LENGTH | 请求正文的长度(作为字符串) |
CONTENT_TYPE | 请求正文的 MIME 类型 |
HTTP_ACCEPT | 可接受的响应内容类型 |
HTTP_ACCEPT_ENCODING | 可接受的响应编码 |
HTTP_ACCEPT_LANGUAGE | 可接受的响应语言 |
HTTP_HOST | 客户端发送的 HTTP Host 头 |
HTTP_REFERER | 引用页面 ( 如果有的话 ) |
HTTP_USER_AGENT | 客户端的用户代理字符串 |
QUERY_STRING | 查询字符串,作为单个(未解析的)字符串 |
REMOTE_ADDR | 客户端的IP地址 |
REMOTE_HOST | 客户端的主机名 |
REMOTE_USER | Web 服务器验证的用户(如果有) |
REQUEST_METHOD | 一个字符串,例如"GET" or "POST" |
SERVER_NAME | 服务器的主机名 |
SERVER_PORT | 服务器的端口(作为字符串) |
使用JSON传递数据
路由
使用应用urls.py
视图函数
1 | # 语法:path('路径/',视图函数) |
视图
定义Json
视图函数
1 | def index(request): |
Postman
使用Postman模拟传递数据
HttpResPonse对象
视图在接收请求并处理后,必须返回HttpResponse对象或子对象。
HttpRequest对象由Django创建,HttpResponse对象由开发人员创建。
HttpResponse
使用django.http.HttpResponse来构造响应对象
1 | HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码) |
也可通过HttpResponse对象属性来设置响应体、响应体数据类型、状态码;
响应头可以直接将HttpResponse对象当做字典进行响应头键值对的设置。
1 | from django.http import HttpResponse # 导包 |
HttpResponse子类
Django提供了一系列HttpResponse的子类,可以快速设置状态码,这些类在 django.http 中。
More Actions类名 | 描述 |
---|---|
HttpResponseRedirect | 构造函数的参数有一个:重定向的路径。 它可以是一个完整的URL(例如, ‘http:www.baidu.com' )或者不包括域名的绝对路径(如 ‘/search/‘ )。 注意它返回 HTTP 状态码 302。 |
HttpResponsePermanentRedirect | 类似 HttpResponseRedirect , 但是它返回一个永久转义 (HTTP状态码 301),而不是暂时性转移(状态码302)。 |
HttpResponseNotModified | 构造函数没有任何参数。用它来表示这个页面在上次请求后未改变。 |
HttpResponseBadRequest | 类似 HttpResponse ,但使用400状态码。 |
HttpResponseNotFound | 类似 HttpResponse ,但使用404状态码。 |
HttpResponseForbidden | 类似 HttpResponse ,但使用403状态码。 |
HttpResponseNotAllowed | 类似 HttpResponse ,但使用405状态码。它必须有一个参数:允许方法的列表。(例如, [‘GET’, ‘POST’] )。 |
HttpResponseGone | 类似 HttpResponse ,但使用410状态码。 |
HttpResponseServerError | 类似 HttpResponse ,但使用500状态码。 |
JsonResponse
若要返回json数据,可以使用JsonResponse来构造响应对象
作用:帮助我们将数据转换为json字符串
设置响应头Content-Type为 application/json
实例使用:
在视图中 创建json数据
1
2
3
4
5
6
7from django.http import JsonResponse # 导包
def responseJson(request):
# json数据
datalist = {'id': 1024, 'name': 'Shrimps', 'password': 123456, 'job': 'Front-end engineer'}
# 返回json数据
return JsonResponse(datalist)在路由中 引入json
1
2
3
4
5from 应用名.views import responseJson # 引用
urlpatterns = [
path('jsonTest/', responseJson) # 使用
]页面显示效果
类视图
以函数的形式进行定义的视图就是函数视图,视图函数便于理解,但是遇到一个视图函数对应的路径提供了多种不同的HTTP请求方式的支持时(get,post,delete,put),需要在一个函数中写不同的业务逻辑,代码的可读性和复用性就很底, 所以,我们引入类视图进行解决.
类视图的优点:
- 代码可读性好
- 类视图相对于函数视图有更高的复用性,如果其他地方需要使用到某个类的某个特定方法,直接继承该类的视图就可以了
类视图的使用
定义类视图需要继承自的Django提供的父类的View:
- 导入方法:
1 | from django.views.generic import View |
配置路由时,需要使用类视图的as_view()方法来注册添加
- 应用中 -
views.py
定义类视图
1 | # 类视图方法 |
- 应用中 -
urls.py
注册路由
1 | from 应用名.views import RegisterView |
- templates中 -
register.html
映射到页面
1 |
|