Django中间件
Django中间件
中间件是一个用来处理Django的请求和响应的框架级别的钩子。本质上就是一个类
中间件是介于reuqest和response处理之间的一道处理过程,用于在全局范围内改变Django的输入和输出。
中间件可以定义五个方法:
- process_request(self,request)
- process_view(self, request, view_func, view_args, view_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
- process_response(self, request, response)
4个特征: 执行时间、执行顺序、参数、返回值
创建一个py文件写中间件
from django.utils.deprecation import MiddlewareMixin # 先导入类 class Md1(MiddlewareMixin): # 类名自己写 def process_request(self, request): # print(id(request)) print('MD1 process_request ') # return HttpResponse('md1') def process_response(self, request, response): # print(id(response)) print('MD1 process_response ') return response def process_view(self, request, view_func, view_args, view_kwargs): # print(view_func) # print(view_args) # print(view_kwargs) print('MD1 process_view ') # return HttpResponse('md1 process_view ') def process_exception(self, request, exception): print('MD1 process_exception ') # return HttpResponse('错误处理完成') def process_template_response(self, request, response): print('MD1 process_template_response ') return response
对中间件进行注册
# setting中 MIDDLEWARE = [ .... 'app01.mymiddlewares.middleware.Md1', # 中间件的路径,写到类名 'app01.mymiddlewares.middleware.MD2', ]
process_request(self,request)
执行时间:视图函数之前 参数:request —— 》 和视图函数中是同一个request对象 执行顺序:按照注册的顺序 顺序执行 返回值: ?None : 正常流程 ?HttpResponse: 后面的中间的process_request、视图函数都不执行,直接执行当前中间件中的process_response方法,倒叙执行之前的中间中process_response方法。
process_response(self, request, response)
执行时间:视图函数之后 参数: ?request —— 》 和视图函数中是同一个request对象 ?response ——》 返回给浏览器响应对象 执行顺序:按照注册的顺序 倒叙执行 返回值: HttpResponse:必须返回response对象
process_view(self, request, view_func, view_args, view_kwargs)
执行时间:视图函数之前,process_request之后 参数: ? request —— 》 和视图函数中是同一个request对象 ? view_func ——》 视图函数 ? view_args ——》 视图函数的位置参数 ? view_kwargs ——》 视图函数的关键字参数 执行顺序:按照注册的顺序 顺序执行 返回值: ? None : 正常流程 ? HttpResponse: 后面的中间的process_view、视图函数都不执行,直接执行最后一个中间件中的process_response方法,倒叙执行之前的中间中process_response方法。
process_exception(self, request, exception)
执行时间(触发条件):视图层面有错时才执行 参数: ? request —— 》 和视图函数中是同一个request对象 ? exception ——》 错误对象 执行顺序:按照注册的顺序 倒叙执行 返回值: ? None : 交给下一个中间件取处理异常,都没有处理交由django处理异常 ? HttpResponse: 后面的中间的process_exception不执行,直接执行最后一个中间件中的process_response方法,倒叙执行之前的中间中process_response方法。
process_template_response(self,request,response)
执行时间(触发条件):视图返回的是一个templateResponse对象或者对象有一个render方法 参数: ? request —— 》 和视图函数中是同一个request对象 ? response ——》 templateResponse对象 执行顺序:按照注册的顺序 倒叙执行 返回值: ? HttpResponse:必须返回response对象,可以处理模板或者数据 from django.template.response import TemplateResponse def process_template_response(self,request,response): response.template_name = '模板的文件名' # 可以改模板内容 response.context_data = {} # 可以改数据字典的内容 return response
总结流程
请求到达中间件之后,先按照正序执行每个注册中间件的process_reques方法,process_request方法返回的值是None,就依次执行,如果返回的值是HttpResponse对象,不再执行后面的process_request方法,而是执行当前对应中间件的process_response方法,将HttpResponse对象返回给浏览器。
process_request方法都执行完后,匹配路由,找到要执行的视图函数,先不执行视图函数,先执行中间件中的process_view方法,process_view方法返回None,继续按顺序执行,所有process_view方法执行完后执行视图函数。假如中间件3 的process_view方法返回了HttpResponse对象,则4,5,6的process_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行。
process_template_response和process_exception两个方法的触发是有条件的,执行顺序也是倒序。总结所有的执行流程如下:
Django请求流程图