Django的视图层

一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py的文件中。

http请求中产生两个核心对象:

1、http请求—->HttpRequest对象,用户请求相关的所有信息(对象)

2、http响应—->HttpResponse对象,响应字符串

例子:

1
2
3
4
5
6
7
8
# 新建views1.py
from django.http import HttpResponse
def index(request):
return HttpResponse("你好")

# 在urls.py中修改配置
from . import views1
path('', views1.index, name='index'),

例子里,我们用到的request,就是HttpRequest对象。HttpResponse("你好"),就是HttpResponse对象,它向http请求响应了一段字符串。

视图函数,就是围绕着HttpRequestHttpResponse这两个对象进行的。

HttpRequest对象

request请求信息和属性和方法。

属性和方法包含下面几个:

request.path

这个主要是用来获取访问文件路径

1
2
3
4
5
from django.shortcuts import render,HttpResponse
def index(request):
print(request.path)
print(request.get_full_path())
return render(request,'index.html')

如果我们是通过127.0.0.1:8000/post/23?page=1请求的话。

1
2
request.path`的结果为:`/post/23
request.get_full_path()`的结果为:`/post/23?page=1

request.method

获取请求中使用的HTTP方式(POST/GET)

1
2
3
4
from django.shortcuts import render,HttpResponse
def index(request):
print(request.method)
return render(request,'index.html')

request.body

含所有请求体信息 是bytes类型

request.GET

获取HTTP GET方式请求传参,的参数(字典类型)

1
2
3
4
from django.shortcuts import render,HttpResponse
def index(request):
print(request.GET)
return render(request,'index.html')

如果我们通过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_LENGTHCONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,
都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。
所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。

request.COOKIES

包含所有cookies的标准Python字典对象;keysvalues都是字符串。

request.FILES

包含所有上传文件的类字典对象;FILES中的每一个Key都是标签中name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:filename:上传文件名,用字符串表示、content_type:上传文件的Content Typecontent:上传文件的原始内容。

request.user

是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你可以通过useris_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
2
3
4
5
6
7
def index(request):
blog_index = models.Article.objects.all().order_by('-id')
print(request.body)
context = {
'blog_index':blog_index,
}
return render(request, 'index.html',context)

参数:
request: 用于生成响应的请求对象。
template_name:要使用的模板的完整名称,可选的参数
context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。
status:响应的状态码。默认为200。

render方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的html静态文件返回给浏览器。这里一定要注意:render渲染的是模板。

我们的模板是这样写的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html lang="en">
<head>
<meta charset="UTF-8">
<title>博客首页</title>
</head>
<body>
<div style="margin: 0 auto">
<ul>
<h3>最新文章</h3>
{% for x in blog_index %}
<li>{{ x.title }}</li>
{% endfor %}
</ul>
</div>
</body>
</html>

上面 之间包括的就是我们要从数据库取出的数据,进行填充。对于这样一个没有填充数据的`html`文件,浏览器是不能进行渲染的,所以,对于上述之间的内容先要被render进行渲染之后,才能发送给浏览器。

Views里是这样写的:

1
2
3
4
5
6
7
def index(request):
blog_index = models.Article.objects.all().order_by('-id')#从数据库中取出文章数据
print(request.body)
context = {
'blog_index':blog_index,#将数据保存在blog_index
}
return render(request, 'index.html',context)#通过render进行模板渲染

redirect函数

多用于页面跳转。

redirect的参数可以是:
一个模型:将调用模型的get_absolute_url() 函数
一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称
一个绝对的或相对的URL,将原封不动的作为重定向的位置。
默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。

示例:

传递一个对象,将调用get_absolute_url() 方法来获取重定向的URL

1
2
3
4
5
from django.shortcuts import redirect
def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object)

传递一个视图的名称,可以带有位置参数和关键字参数;将使用reverse() 方法反向解析URL:

1
2
3
def my_view(request):
...
return redirect('some-view-name', foo='bar')

传递要重定向的一个硬编码的URL:

1
2
3
def my_view(request):
...
return redirect('/some/url/')

也可以是一个完整的URL:

1
2
3
def my_view(request):
...
return redirect('https://www.django.cn/')

默认情况下,redirect() 返回一个临时重定向。以上所有的形式都接收一个permanent 参数;如果设置为True,将返回一个永久的重定向:

1
2
3
4
ef my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object, permanent=True)

renderredirect两者区别:    
第一,假如render返回一个登陆成功后的页面,刷新该页面将回复到跳转前页面。而redirect则不会
第二,如果页面需要模板语言渲染,需要的将数据库的数据加载到html,那么render方法则不会显示这一部分,render返回一个登陆成功页面,不会经过url路由分发系统,也就是说,不会执行跳转后url的视图函数。这样,返回的页面渲染不成功;而redirect是跳转到指定页面,当登陆成功后,会在url路由系统进行匹配,如果有存在的映射函数,就会执行对应的映射函数。