中间件
功能作用
1.介于request与response处理之间的一道处理过程,并且在全局上改变django的输入与输出。
2.修改请求。例如被传送到view中的HttpRequest对象。 或者想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。
3. 在view执行之前做一些操作,可以用 middleware来实现。
Django默认的Middleware
:
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', ]
中间件中的方法:
process_request process_response
process_view
process_exception
先理解django项目运行流程
django项目
1.wsgiref模块(socket)
报文data--->envision--->request对象
2.中间键,第一层处理业务的流程
3.控制器(路由+视图)
4.models模型层,模板层
5.视图处理后把数据返回给中间件,中间件再将数据返回给客户端
大致的流程如下图:

自定义中间件 注意 :自定的中间件必须继承 MiddlewareMixin from django.utils.deprecation import MiddlewareMixin 1.在app 中创建Mymiddlewares.py 的自定义文件 2. 在该文件中导入from django.utils.deprecation import MiddlewareMixin 3.在Mymiddleware.py 中创建中间件 4.在settings 中添加中间件配置 格式 :” app1.自定义中间件文件.中间件名字(类名)”
Mymiddlewares.py文件中自定义中间件

from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self,request): print("process_request M1....") def process_response(self,request,response): print("process_response M1 ...") return response class M2(MiddlewareMixin): def process_request(self, request): print("process_request M2....") def process_response(self, request, response): print("process_response M2 ...") return response
中间件的工作流程:
视图函数:
from django.shortcuts import render,HttpResponse # Create your views here. def index(request): print("执行index视图函数") return HttpResponse("ok")
情况一:
1.自定义中间件M1 和M2 ,process_request都不return ,process_response都return时:
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self,request): print("process_request M1....") def process_response(self,request,response): print("process_response M1 ...") return response class M2(MiddlewareMixin): def process_request(self, request): print("process_request M2....") def process_response(self, request, response): print("process_response M2 ...") return response
服务端打印结果:
process_request M1....
process_request M2....
执行index视图函数
process_response M2 ...
process_response M1 ...
流程图:
情况二:
1.如果中间件1中的process_request ,开始就return 结果
那么就不会走中间件2以及视图函数,直接走中间件1的request.response函数,直接返回给用户结果
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self,request): print("M1 在process_request 时就return 了") return HttpResponse("直接返回给用户的内容") #此处return后可以不让用户进入视图函数 def process_response(self,request,response): print("process_response M1 ...") return response class M2(MiddlewareMixin): def process_request(self, request): print("process_request M2....") def process_response(self, request, response): print("process_response M2 ...") return response
服务端打印的结果:
M1 在process_request 时就return 了 [10/Jan/2019 20:38:05] "GET /index/ HTTP/1.1" 200 30 process_response M1 ...
执行流程图:
情况三:process_view
process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行。
1.process_view 中不return 时,如:
Mymiddleware.py 文件中
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self,request): print("process_request M1 ...") def process_response(self,request,response): print("process_response M1 ...") return response def process_view(self,request,callback, callback_args, callback_kwargs):
#callback 视图
print("M1 process_view") class M2(MiddlewareMixin): def process_request(self, request): print("process_request M2....") def process_response(self, request, response): print("process_response M2 ...") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("M2 process_view")
后端结果:
process_request M1 ...
process_request M2....
M1 process_view
M2 process_view
执行index视图函数
process_response M2 ...
process_response M1 ...
请求过程:
2. process_view 在M1 中return 出现的情况:
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self,request): print("process_request M1 ...") def process_response(self,request,response): print("process_response M1 ...") return response def process_view(self,request,callback, callback_args, callback_kwargs): print("M1 process_view") obj = callback(callback_args) # callback(callback_args) 就是执行对应的视图函数,obj就是视图函数的响应对象 #callback_args 视图函数的参数 ,obj返回给 M2 的response
return obj class M2(MiddlewareMixin): def process_request(self, request): print("process_request M2....") def process_response(self, request, response): print("process_response M2 ...") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("M2 process_view")
服务端的打印结果:
process_request M1 ...
process_request M2....
M1 process_view
执行index视图函数 #为process_view 中callback(callback_args) 提前执行的结果
process_response M2 ...
process_response M1 ...
流程图:
process_exception
Mymiddleware.py:
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self,request): print("process_request M1 ...") def process_response(self,request,response): print("process_response M1 ...") return response def process_view(self,request,callback, callback_args, callback_kwargs): print("M1 process_view") def process_exception(self,request,exception): print("process_exception M1") return HttpResponse("错误的") class M2(MiddlewareMixin): def process_request(self, request): print("process_request M2....") def process_response(self, request, response): print("process_response M2 ...") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("M2 process_view") # obj = callback(callback_args) # return obj def process_exception(self, request, exception): print("process_exception...M2") return HttpResponse("error")
视图中:
from django.shortcuts import render,HttpResponse # Create your views here. def index(request): print("执行index视图函数") yun return HttpResponse("ok")
后端打印结果:
process_request M1 ...
process_request M2....
M1 process_view
M2 process_view
执行index视图函数
process_exception...M2
process_response M2 ...
process_response M1 ...
当视图中出现错误时,先执行
M2 process_exception,之后的M1中process_exception 就不执行了,直接去执行process_response