Django的视图层
一个视图函数,简称视图,是一个简单的Python
函数,它接受Web请求并且返回Web
响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py
的文件中。
http
请求中产生两个核心对象:
1、http
请求—->HttpRequest
对象,用户请求相关的所有信息(对象)
2、http
响应—->HttpResponse
对象,响应字符串
例子:
1 | # 新建views1.py |
例子里,我们用到的request
,就是HttpRequest
对象。HttpResponse("你好")
,就是HttpResponse
对象,它向http
请求响应了一段字符串。
视图函数,就是围绕着HttpRequest
和HttpResponse
这两个对象进行的。
HttpRequest
对象
request
请求信息和属性和方法。
属性和方法包含下面几个:
request.path
这个主要是用来获取访问文件路径
1 | from django.shortcuts import render,HttpResponse |
如果我们是通过127.0.0.1:8000/post/23?page=1请求的话。
1 | request.path`的结果为:`/post/23 |
request.method
获取请求中使用的HTTP方式(POST/GET)
1 | from django.shortcuts import render,HttpResponse |
request.body
含所有请求体信息 是bytes
类型
request.GET
获取HTTP GET
方式请求传参,的参数(字典类型)
1 | from django.shortcuts import render,HttpResponse |
如果我们通过127.0.0.1:8000/post/?fenlei=123 & page=3 请求。
获取到:<QueryDict: {' page': ['456'], 'fenlei': ['123 ']}>
request.POST
获取POST
请求的数据(类字典对象) 请求体里拿值。服务器收到空的POST
请求的情况也是可能发生的,也就是说,表单form
通过服务器收到空的POST
请求的情况也是可能发生的,也就是说,表单form
通过if request.POST
来判断是否使用了HTTP POST
方法;应该使用 if request.method=="POST"
。
request.META
一个标准的Python
字典,包含所有的HTTP
首部。具体的头部信息取决于客户端和服务器,下面是一些示例:
CONTENT_LENGTH
—— 请求的正文的长度(是一个字符串)。CONTENT_TYPE
—— 请求的正文的MIME
类型。HTTP_ACCEPT
—— 响应可接收的Content-Type
。HTTP_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_
前缀。
所以,一个叫做 X-Bender
的头部将转换成 META
中的 HTTP_X_BENDER
键。
request.COOKIES
包含所有cookies
的标准Python
字典对象;keys
和values
都是字符串。
request.FILES
包含所有上传文件的类字典对象;FILES
中的每一个Key
都是标签中name属性的值,FILES
中的每一个value
同时也是一个标准的python字典对象,包含下面三个Keys:filename
:上传文件名,用字符串表示、content_type
:上传文件的Content Type
、content
:上传文件的原始内容。
request.user
是一个django.contrib.auth.models.User
对象,代表当前登陆的用户。如果访问用户当前没有登陆,user
将被初始化为django.contrib.auth.models.AnonymousUser
的实例。你可以通过user
的is_authenticated()
方法来辨别用户是否登陆:if request.user.is_authenticated();
只有激活Django
中的AuthenticationMiddleware
时该属性才可用。
request.session
唯一可读写的属性,代表当前会话的字典对象;自己有激活Django
中的session
支持时该属性才可用
request.GET.get('name')
拿到GET
请求里name
的值,如果某个键对应有多个值,则不能直接用get
取值,需要用getlist
,如:request.POST.getlist("hobby")
。
HttpResponse
对象
对于HttpRequest
请求对象来说,是由django
自动创建的,但是,HttpResponse
响应对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse
响应对象。HttpResponse
类在django.http.HttpResponse
。
HttpResponse
对象的常用方法:
render
函数
将指定页面渲染后返回给浏览器。
render(request, template_name[, context])
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse
对象。
1 | def index(request): |
参数:request
: 用于生成响应的请求对象。template_name
:要使用的模板的完整名称,可选的参数context
:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。content_type
:生成的文档要使用的MIME
类型。默认为DEFAULT_CONTENT_TYPE
设置的值。status
:响应的状态码。默认为200。
render
方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的html静态
文件返回给浏览器。这里一定要注意:render
渲染的是模板。
我们的模板是这样写的:
1 | <html lang="en"> |
上面 之间包括的就是我们要从数据库取出的数据,进行填充。对于这样一个没有填充数据的`html`文件,浏览器是不能进行渲染的,所以,对于上述
之间的内容先要被render
进行渲染之后,才能发送给浏览器。
Views
里是这样写的:
1 | def index(request): |
redirect
函数
多用于页面跳转。
redirect
的参数可以是:
一个模型:将调用模型的get_absolute_url()
函数
一个视图,可以带有参数:将使用urlresolvers.reverse
来反向解析名称
一个绝对的或相对的URL
,将原封不动的作为重定向的位置。
默认返回一个临时的重定向;传递permanent=True
可以返回一个永久的重定向。
示例:
传递一个对象,将调用get_absolute_url()
方法来获取重定向的URL
:
1 | from django.shortcuts import redirect |
传递一个视图的名称,可以带有位置参数和关键字参数;将使用reverse()
方法反向解析URL:
1 | def my_view(request): |
传递要重定向的一个硬编码的URL:
1 | def my_view(request): |
也可以是一个完整的URL:
1 | def my_view(request): |
默认情况下,redirect()
返回一个临时重定向。以上所有的形式都接收一个permanent
参数;如果设置为True
,将返回一个永久的重定向:
1 | ef my_view(request): |
render
和redirect
两者区别:
第一,假如render
返回一个登陆成功后的页面,刷新该页面将回复到跳转前页面。而redirect则不会
第二,如果页面需要模板语言渲染,需要的将数据库的数据加载到html
,那么render
方法则不会显示这一部分,render
返回一个登陆成功页面,不会经过url
路由分发系统,也就是说,不会执行跳转后url
的视图函数。这样,返回的页面渲染不成功;而redirect
是跳转到指定页面,当登陆成功后,会在url
路由系统进行匹配,如果有存在的映射函数,就会执行对应的映射函数。