Django入门到放弃之中间件
修改请求,即传送到 view 中的 HttpRequest 对象。
修改响应,即 view 返回的 HttpResponse 对象。
1. process_request
1. 执行时间
在视图函数之前执行
2. 参数
request 和视图中的request是同一个
3. 返回值
返回None
返回response对象
不执行后面中间的process_request方法和视图
直接执行当前值中间件的process_response方法
4. 执行顺序
按照注册的顺序执行
process_request 方法有一个参数 request,这个 request 和视图函数中的 request 是一样的。
process_request 方法的返回值可以是 None 也可以是 HttpResponse 对象。
返回值是 None 的话,按正常流程继续走,交给下一个中间件处理。
返回值是 HttpResponse 对象,Django 将不执行后续视图函数之前执行的方法以及视图函数,直接以该中间件为起点,倒序执行中间件,且执行的是视图函数之后执行的方法。
process_request 方法是在视图函数之前执行的。
当配置多个中间件时,会按照 MIDDLEWARE中 的注册顺序,也就是列表的索引值,顺序执行。
不同中间件之间传递的 request 参数都是同一个请求对象。
代码示例:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行
process_view
1. 执行时间
在视图函数之前,process_request之后执行
2. 参数
request 是 HttpRequest 对象。
view_func 是 Django 即将使用的视图函数。
view_args 是将传递给视图的位置参数的列表。
view_kwargs 是将传递给视图的关键字参数的字典。
view_args 和 view_kwargs 都不包含第一个视图参数(request)。
3. 返回值
返回 None 正常执行
返回 response对象 不执行后面的process_view和视图,直接执行所有中间件的process_response方法
返回 view_func(request) Django 将不执行后续视图函数之前执行的方法,提前执行视图函数,然后再倒序执行视图函数之后执行的方法
4。执行顺序
按照注册的顺序执行
process_view 方法是在视图函数之前,process_request 方法之后执行的。
当最后一个中间件的 process_request 到达路由关系映射之后,返回到第一个中间件 process_view,然后依次往下,到达视图函数
代码示例:
class MD1(MiddlewareMixin):
def process_request(self, request,callback,callback_args,callback_kwargs):
#callback 就是视图函数
#res = callback(request)
print("md1 process_request 方法。", id(request)) #在视图之前执行
def process_response(self,request, response): :#基于请求响应
print("md1 process_response 方法!", id(request)) #在视图之后
return response
def process_view(self,request, view_func, view_args, view_kwargs):
print("md1 process_view 方法!") #在视图之前执行 顺序执行
#return view_func(request)
process_template_response(条件触发:视图返回的response有render方法)
1. 执行时间
在视图函数之后,process_response之前执行
2. 参数
3. 返回值
返回 response对象
4. 执行顺序
按照注册的倒序执行,执行完所有的process_template_response方法后执行response.render方法
process_exception(有条件触发:有错误才执行)
1. 执行时间
在视图函数之后,process_response之前执行
2. 参数
exception 错误对象
3. 返回值
返回 None 不对错误进行处理,交给下一个中间件进行处理
返回 response对象 下一个中间的process_exception不执行,直接执行所有中间件的process_response方法
4. 执行顺序
按照注册的倒序执行
代码示例:
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行
def process_response(self,request, response): :#基于请求响应
print("md1 process_response 方法!", id(request)) #在视图之后
return response
def process_view(self,request, view_func, view_args, view_kwargs):
print("md1 process_view 方法!") #在视图之前执行 顺序执行
#return view_func(request)
def process_exception(self, request, exception):#引发错误 才会触发这个方法
print("md1 process_exception 方法!")
# return HttpResponse(exception) #返回错误信息
process_response
1. 执行时间
在视图函数之后执行
2. request, response
request 和视图中的request是同一个
response 返回的response对象
3. 返回值
返回response对象
4. 执行顺序
按照注册的倒序执行
代码示例:
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行
def process_response(self,request, response): :#基于请求响应
print("md1 process_response 方法!", id(request)) #在视图之后
return response
当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。
process_request可以干什么?
-写一个中间件,不管前端用什么编码,在requset.data中都有post的数据
-频率限制(限制某个ip地址,一分钟只能访问5次)
-登录认证(只要没登录,重定向到login路径)、
-记录用户访问日志(ip,时间,访问路径)
process_response可以干什么?内部有response对象
-统一给所有(某几个路径)加cookie
-统一给所有(某几个路径)加响应头
process_view 路由匹配成功和视图函数执行之前执行(callback就是视图函数)
def process_view(self, request, callback, callback_args, callback_kwargs):
# print(callback)
# print(callback_args)
# print(callback_kwargs)
#在调用函数前执行点什么
res=callback(request)
#在视图函数执行后做点什么 类似装饰器
print("中间件1的process_view")
return res
process_exception 视图函数出错,会执行它(全局异常捕获)(记录日志,哪个ip地址,访问哪个路径,出的错)
# 全局异常捕获,返回4开头的
def process_exception(self, request, exception):
print(exception)
return render(request,'error.html')
1、执行完所有的request方法 到达视图函数。
2、执行中间件的其他方法
3、经过所有response方法 返回客户端。
注意:如果在其中1个中间件里 request方法里 return了值,就会执行当前中间的response方法,返回给用户 然后 报错。。不会再执行下一个中间件。
-写一个类,继承MiddlewareMixin #from django.utils.deprecation import MiddlewareMixin
-里面写方法process_request等方法
-在setting中配置(注意,放在前和放在后)
MIDDLEWARE = [
...
'app01.mymiddle.MyMiddleware1',
...
]
"一劳永逸" 的话,有是有的,而 "一劳永逸" 的事却极少