中间件的概念
中间件其实就是介于request与response处理之间的处理过程,也就是说在他可以改变django的输入输出,而且改变是全局的,比如修改请求如客户端发送的HttpRequest对象,或者修改服务端返回的HttpResponse,这些都可以通过中间件来实现。
django中的中间件
setting中的中间件:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', #session中间件 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', #认证中间件 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
wsgi的作用:
wsgi是协议,而wsgiref是django封装wsgi协议的模块,而这个模块在这儿的作用是:客户端浏览器发送的请求是http协议封装的请求,wsgiref模块将请求按照http协议解析后交给中间件处理,中间件处理完给视图,视图函数发送响应,响应首先通过中间件,然后wsgireef模块又将响应按照http协议封装,最后返回给客户端
中间件:
首先我们点进中间件源码时可以看到中间件都有的两个方法:process_request、process_response而这两个方法前者为请求后者为响应,请求时按照中间件从上到下的顺序,响应时按照从下到上。
此图省略了wsgi,基本的请求响应流程就是这样,除此之外,有些中间件除了这两个方法之外还有process_view的方法:
这个图的流程为:当某个中间件的process_request方法有返回值时,请求中断,后面的处理都不执行,直接执行这个中间件的process_response方法开始返回响应,如果中间件没有返回值继续执行后面的中间件,process_request执行完后走process_view方法,当某个中间件的process_view有返回值时,从最后一个中间件的process_response开始返回响应不会执行后面的process_view方法。
完整的流程图:
对于中间件流程的验证
1.创建django项目:
def index(request): print("view函数...") return HttpResponse("ok")
2.自定义一个中间件:
我们可以仿照django默认的中间件自己写一个类,继承MiddlewareMixin需要导入:
from django.utils.deprecation import MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class Md1(MiddlewareMixin): def process_request(self,request): print("Md1请求") def process_response(self,request,response): print("Md1返回") return response class Md2(MiddlewareMixin): def process_request(self,request): print("Md2请求") #return HttpResponse("Md2中断") def process_response(self,request,response): print("Md2返回") return response
将中间件文件创建在根目录:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'Mymiddlewares.Md1', 'Mymiddlewares.Md2', ]
运行结果:
Md1请求 Md2请求 view函数... Md2返回 Md1返回
如果将里面注释的请求二中的return HttpResponse取消注释,也就是如果请求到达请求2不符合条件是程序将请求直接发给中间件2返回:
结果:
Md1请求 Md2请求 Md2返回 Md1返回
process_view:
process_view(self, request, callback, callback_args, callback_kwargs)
结果:
Md1请求 Md2请求 Md1view Md2view view函数... Md2返回 Md1返回
最后一个中间件的Process_request到达路由关系映射之后,返回中间件1的Process_view然后依次往下执行,到达views函数,最后通过Process_resonse依次返回给客户端
process_exception
process_exception(self, request, exception)
class Md1(MiddlewareMixin): def process_request(self,request): print("Md1请求") #return HttpResponse("Md1中断") def process_response(self,request,response): print("Md1返回") return response def process_view(self, request, callback, callback_args, callback_kwargs): # return HttpResponse("hello") # response=callback(request,*callback_args,**callback_kwargs) # return response print("md1 process_view...") def process_exception(self): print("md1 process_exception...") class Md2(MiddlewareMixin): def process_request(self,request): print("Md2请求") # return HttpResponse("Md2中断") def process_response(self,request,response): print("Md2返回") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("md2 process_view...") def process_exception(self): print("md1 process_exception...")
结果:
Md1请求 Md2请求 md1 process_view... md2 process_view... view函数... Md2返回 Md1返回
将中间件md2的process_exception修改为:
def process_exception(self,request,exception): print("md2 process_exception...") return HttpResponse("error")
结果:
Md1请求 Md2请求 md1 process_view... md2 process_view... view函数... md2 process_exception... Md2返回 Md1返回