Django视图系统
-
Django的View
- 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。
- 响应可以是网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。
- 无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为
views.py
的文件中。 - 简而言之,视图,就是你写业务逻辑的地方。
-
一个简单的视图示例
-
下面是一个在
views.py
中以HTML文档形式返回当前日期和时间的视图:from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
-
让我们来逐行解释下上面的代码:
首先,我们从
django.http
模块导入了HttpResponse
类,以及Python的datetime
库。-
接着,我们定义了
current_datetime
函数。它就是视图函数。每个视图函数都使用HttpRequest
对象作为第一个参数,并且通常称之为request
。注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为
current_datetime
,是因为这个名称能够比较准确地反映出它实现的功能。 这个视图会返回一个
HttpResponse
对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse
对象。Django使用请求和响应对象来通过系统传递状态。当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。每个视图负责返回一个HttpResponse对象。
-
-
FBV和CBV
-
FBV:基于函数写的view称为FBV。
def register(request): ''' 这是一个注册页面的函数 :param request: :return: ''' if request.method == 'POST': # 用户提交注册信息 username = request.POST.get('username', None) # 通过models.UserInfo.objects对象在数据库中创建这条记录 models.UserInfo.objects.create(name=username) # 数据创建成功后直接跳转到user_list页面 return redirect('/user_list/') # 如果不为POST,则执行下面的语句 return render(request, 'register.html')
-
CBV:基于类写的view称为CBV。
from django.views import View class Registrer(View): # 需要继承View def get(self, request): return render(request, 'register.html') def post(self, request): username = request.POST.get('username', None) # 通过models.UserInfo.objects对象在数据库中创建这条记录 models.UserInfo.objects.create(name=username) # 数据创建成功后直接跳转到user_list页面 return redirect('/user_list/')
需要注意的是,若使用CBV,urls.py中调用类的时候必须加上
.as_Views()
# urls.py中 from django.contrib import admin from django.urls import path from app import views urlpatterns = [ # ...... path('register/', views.Register.as_View()), # ...... ]
-
-
视图装饰器
Django 提供很多装饰器,它们可以为视图支持多种 HTTP 特性。查看 装饰类 来了解如何在基于类的视图中使用这些装饰器。
-
允许的 HTTP 方法
在 django.views.decorators.http 中的装饰器可以用来根据请求方法来限制对视图的访问。如果条件不满足,这些装饰器将返回 django.http.HttpResponseNotAllowed 。
-
require_http_methods(request_method_list)
装饰器可以要求视图只接受特定的请求方法。from django.views.decorators.http import require_http_methods @require_http_methods(["GET", "POST"]) # 注意:请求方法应该是大写。 def my_view(request): # I can assume now that only GET or POST requests make it this far # ... pass
require_GET()
装饰器可以要求视图只接受 GET 方法。require_POST()
装饰器可以要求视图只接受 POST 方法。require_safe()
装饰器可以要求视图只接收 GET 和 HEAD 方法。这些方法通常被认为是安全的,因为它们除了检索请求的资源外,没有特别的操作。
注解
Web 服务器自动删除对 HEAD 请求的相应内容,并保持头部不变,所以你可以像处理视图里的 GET 请求一样处理 HEAD 请求。因为一些软件依赖 HEAD 请求(比如链接检测器),因此你需要使用 require_safe 而不是 require_GET 。
-
Request对象和Response对象
-
Request对象(HttpRequest的对象)
-
当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。并且会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。在视图函数中,接收的request常用的属性如下:
request.path_info
:返回用户访问的url,不包括域名、IP、端口和参数。request.method
:所使用的请求方法(GET还是POST),全大写表示。request.GET
:以字典的形式获取HTTP信息中的GET参数。request.POST
:以字典的形式获取HTTP信息中的POST参数。request.body
: 请求体,byte类型 request.POST的数据就是从body里面提取到的。request.scheme
:以字符串形式获取请求的方式(http或https)。request.body
:以byte形式获取请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。request.path
:返回用户访问的url,不包括域名、IP、端口和参数。request.COOKIES
:一个标准的Python 字典,包含所有的cookie。键和值都为字符串。request.FILES
:一个类似于字典的对象,包含所有的上传文件信息。-
request.META
:一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器。CONTENT_LENGTH
:请求的正文的长度(是一个字符串)CONTENT_TYPE
:请求的正文的MIME 类型HTTP_ACCEPT
:响应可接收的Content-TypeHTTP_ACCEPT_ENCODING
:响应可接收的编码。HTTP_ACCEPT_LANGUAGE
:响应可接收的语言。HTTP_HOST
:客服端发送的HTTP Host 头部。HTTP_REFERER
:Referring 页面。HTTP_USER_AGENT
:客户端的user-agent 字符串。QUERY_STRING
:单个字符串形式的查询字符串(未解析过的形式)。REMOTE_ADDR
:客户端的IP 地址。REMOTE_HOST
:客户端的主机名。REMOTE_USER
:服务器认证后的用户。REQUEST_METHOD
:一个字符串,例如"GET" 或"POST"。SERVER_NAME
:服务器的主机名。-
SERVER_PORT
:服务器的端口(是一个字符串)。从上面可以看到,除
CONTENT_LENGTH
和CONTENT_TYPE
之外,请求中的任何 HTTP 首部转换为 META 的键时,都会将所有字母大写并将连接符替换为下划线最后加上HTTP_
前缀。
request.user
:一个AUTH_USER_MODEL
类型的对象,获取当前登录的用户。request.session
:一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django启用会话的支持时才可用。
-
request中常用的方法:
-
request.get_host()
:根据从HTTP_X_FORWARDED_HOST
(如果打开USE_X_FORWARDED_HOST
,默认为False
)和HTTP_HOST
头部信息返回请求的原始主机。如果这两个头部没有提供相应的值,则使用SERVER_NAME
和SERVER_PORT
,在PEP 3333 中有详细描述。USE_X_FORWARDED_HOST
是一个布尔值,用于指定是否优先使用 X-Forwarded-Host 首部,仅在代理设置了该首部的情况下,才可以被使用。 -
request.get_full_path()
:不同于request.path_info
,虽然不包括域名、IP、端口,但会包含参数。 -
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
:返回签名过的Cookie 对应的值,如果签名不再合法则返回django.core.signing.BadSignature
。 -
request.is_secure()
:如果请求时是安全的,则返回True;即请求通是过 HTTPS 发起的。 -
request.is_ajax()
:如果请求是通过XMLHttpRequest
发起的,则返回True
,方法是检查HTTP_X_REQUESTED_WITH
相应的首部是否是字符串XMLHttpRequest
。大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的XMLHttpRequest
调用(在浏览器端),你必须手工设置这个值来让is_ajax()
可以工作。
-
-
-
-
Response对象
- 与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse。HttpResponse类位于django.http模块中。
-
JsonResponse对象
-
JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。
from django.http import JsonResponse def get_josn(): data = {'foo': 'bar'} response = JsonResponse(data) # 默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。response = JsonResponse(data, safe=False) return response
-