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
-