第九章 Django的视图
9.1. View
Django使用请求和响应对象来通过系统传递状态。
当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。
然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。
每个视图负责返回一个HttpResponse对象。
9.1.1 views.py
一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。
响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。
无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。
9.1.2 FBV和CBV
FBV:function based view
CBV:class based view。api开发
1. CBV语法
处理请求的逻辑清晰
# cbv示例 from django.views import View class AddPublisher(View): def get(self, request, *args, **kwargs): """处理get请求""" return response def post(self, request, *args, **kwargs): """处理post请求""" return response def delete(self, request, *args, **kwargs): """处理post请求""" return response
- 使用
# urls.py url(‘^add_publisher/‘, views.AddPublisher.as_view())
as_view流程
项目加载urls.py时,执行类 as_view() —> view函数
请求到来时,执行view函数
实例化类—> self
self.request=request
执行self.dispatch(request, *args, **kwargs)
执行self.dispatch(request, *args, kwargs)**方法
判断请求方式是否被允许(不允许: 405)
允许:通过反射获取对应请求方式的方法—> 赋值给handler
return handlder(request, *args, **kwargs)
不允许:self.http_method_not_allowed —> handler
return handlder(request, *args, **kwargs)
执行handler(request, *args, **kwargs)
9.2. 视图加装饰器
使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。
9.2.1 视图函数加装饰器
# FBV加装饰器 # 装饰器函数 from time import time def timer(func): def inner(*args, **kwargs): start = time() ret = func(*args, **kwargs) print(time() - start) return ret return inner # 给视图函数加装饰器 @timer def fun(): pass
9.2.2 给类方法加装饰器
1. 给某个方法加
导入View类、导入method_decorator
类中定义对应请求的方法
使用带参数的装饰器
# CBV加装饰器 from django.utils.decorators import method_decorator from django.views import View class AddPublisher(View): def get(self, request): # 处理get请求 return response # 给post方法加装饰器 @method_decorator(timer) def post(self, request): # 处理post请求 return response def delete(self, request): # 处理post请求 return response
2. 给dispatch加
给dispatch加装饰器,所有方法都会生效
from django.views import method_decorator @method_decorator(timer) def dispatch(self, request, *args, **kwargs): ret = super().dispatch(request, *args, **kwargs) return ret
3. 在类上加
加在类上,只对指定的name方法有效
from django.views import method_decorator @method_decorator(timer, name=‘get‘) @method_decorator(timer, name=‘post‘) class AddPublisher(View): def get(self, request): # 处理get请求 return response def post(self, request): # 处理post请求 return response def delete(self, request): # 处理post请求 return response
4. 在类上加
指定name=‘dispatch‘,所有方法都生效
from django.views import method_decorator @method_decorator(timer, name=‘dispatch‘) class AddPublisher(View): def get(self, request): # 处理get请求 return response def post(self, request): # 处理post请求 return response def delete(self, request): # 处理post请求 return response
Note(2)
不使用导入method_decorator时
method_decorator
是一个函数,其作用:Converts a function decorator into a method decorator
传入的参数将会发生变化
9.3. reuqest对象
django将请求报文中的请求行、头部信息、内容主体封装成 HttpRequest 类中的属性。
除了特殊说明的之外,其他均为只读的。
9.3.1 request对象的属性
封装请求中的所有内容
常用的是前5种
属性 | 含义 | |
---|---|---|
1 | request.path_info/path | 返回用户访问url,不包括域名 |
2 | request.method | 请求中使用的HTTP方法的字符串表示,全大写表示。 |
3 | request.GET | 包含所有HTTP GET参数的类字典对象,QuerySet |
4 | request.POST | 包含所有HTTP POST参数的类字典对象QuerySet |
5 | request.body | http请求体,byte类型 request.POST的数据就是从body里面提取到的 |
6 | request.scheme | 请求方案,通常为http 或 https |
7 | request.encoding | 编码方式,为None则则表示使用 DEFAULT_CHARSET 的设置,默认为 ‘utf-8‘)。 |
8 | request.FILES | 上传的文件 |
9 | request.META | 获取请求头,全大写,加HTTP, - 变称_s |
10 | request.user | Django提供的auth模块,获得当前登陆的用户 |
11 | request.session | |
12 | request.COOKIES |
- FILES属性示例
file_name = request.FILES.get(‘file‘).name f1 = request.FILES.get(‘f1‘) with open(f1.name, ‘wb‘) as f: # 必须使用chunks()方法,否则会报错 for i in f1.chunks(): f.write(i)
# 保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。从内存读取一次,写磁盘一次。 # 但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。
Note(4)
get请求没有请求体
Encoding
这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。
如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它
FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会 包含数据。否则,FILES 将为一个空的类似于字典的对象。
一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。
9.3.2 方法
方法 | 含义 | |
---|---|---|
1 | request.get_full_path() | url路径,不包含ip端口,包含参数 |
2 | request.get_host() | ip和端口 |
3 | request.is_ajax() | 是否使用ajax |
4 | request.is_secure() | http是否时加密的,https |
5 | request.get_signed_cookies() | 获取加密的cookie |
6 | request.get_raw_url() | 获取全部url |
9.4. response对像
9.4.1. response
与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse。
HttpResponse(‘字符串‘)。类 content-type=‘text/html‘
render(request, ‘模版.html‘, {‘key‘: value})。函数
content进行字符串替换
返回的是HttpResponse对象
render_to_string():进行字符串替换
redirect(‘/重定向的地址/‘)
返回的是HttpResponse对象
JsonResponse
前后端分离通过json传送数据
HttpResponse(dic):前端只能看到key值
dic序列化后,可以在前端显示
content-type=‘text/html‘
9.4.2 HttpResponse使用
HttpResponse类位于django.http模块中。
1. 传递字符串
# 导入 HttpResponse 类 from django.http import HttpResponse response = HttpResponse(‘welcom to our site‘) response = HttpResponse(‘Text only, please‘, content_type=‘text/plain‘)
2. 设置或删除响应头信息
response = HttpResponse() response[‘Content-Type‘] = ‘text/html; charset=UTF-8‘ del response[‘Content-Type‘]
3. 属性
HttpResponse.content:响应内容
HttpResponse.charset:响应内容的编码
HttpResponse.status_code:响应的状态码
9.5. JsonResponse对象
JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。
from django.http.response import JsonResponse def json_data(request): data = [‘name‘:‘henry‘, ‘age‘: 19] ret = HttpResponse(data) # 自己序列化,并指定类型(不导入模块的情况下使用) ret[‘Content-Type‘] = ‘applicatoin/json‘ return ret # 或 return HttpResponse(data,content-type = ‘applicatoin/json‘) # 前端获取数据会自动反序列化
# 默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。 return JsonResponse([1,2,3],safe=False)
9.6. shortcut functions
9.6.1 render()
1. render的使用
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
from django.shortcuts import render def index(request): return render(request, ‘index.html‘, {‘k1‘:v1})
- 等价于
from django.http import HttpResponse from django.template import loader def index(request): # 视图代码 t = loader.get_template(‘index.html‘) d = {‘k1‘:v1} return HttpResponse(t.render(d, request))
2. 参数详解
request: 用于生成响应的请求对象。
template_name:要使用的模板的完整名称,可选的参数
context=None:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
content_type=None:生成的文档要使用的MIME类型。默认为 DEFAULT_CONTENT_TYPE 设置的值。默认为‘text/html‘
status=None:响应的状态码。默认为200。
using=None: 用于加载模板的模板引擎的名称。
9.6.2 redirect()
1. 参数类型
一个模型:将调用模型的
get_absolute_url()
函数一个视图,可以带有参数:将使用
urlresolvers.reverse
来反向解析名称一个绝对的或相对的URL,将原封不动的作为重定向的位置
默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。
2. 示例
def my_view(request): ... # 永久重定向,为False时为临时重定向 return redirect(‘/index/‘, permanent=True)
3. 临时重定向和永久重定向
临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。