一、什么是中间件
请求和响应之间的一道屏障
作用:控制请求和响应
Django默认的中间件 :(在django项目的setting模块中,有一个 MIDDLEWARE_CLASS变量,其中每一个元素就是一个中间件 )
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',]
每一个中间件都有具体的功能
二 、自定义中间件
中间件主要有几个方法:
-from django.utils.deprecation import MiddlewareMixin 先导入 -定义一个类,随意命名,继承MiddlewareMixin class MyMiddleware1(MiddlewareMixin): def process_request(self, request): print('MyMiddleware---->1---->process_request') # 返回HttpRspons对象,直接返回,走自己的process_response # 返回None的时候,继续往下走 # return HttpResponse('i am middle--1') return None def process_response(self, request, response): print('MyMiddleware--->1---->process_response') return response -使用:在setting中注册,是有顺序的, MIDDLEWARE = [ 'app01.mymiddelware.MyMiddleware1', ]
中间件执行顺序:
process_request,从上往下执行,
如果return HttpResponse的对象,直接返回了;
如果return None,继续往下走
中间件的方法:
process_request:请求来的时候,会响应它
process_response:响应回去的时候,会走它
process_view (了解): request, callback(视图函数), callback_args(无名分组的参数), callback_kwargs(有名分组的参数)
三、process_request和process_response
当用户发起请求的时候会依次经过所有的中间件,这个时候请求 procsee_request,最后到达 views的函数中,views函数处理后 ,在依次穿过中间件,这个时候是process_response,最后返回给请求者。
上述截图中的中间件都是Django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin
第一步:导入
from` `django.utils.deprecation ``import` `MiddlewareMixin
第二步 :自定义中间件
from django.utils.deprecation import MiddlewareMixinfrom django.shortcuts import HttpResponseclass Md1(MiddlewareMixin): def process_request(self,request): print("Md1请求") def process_response(self,request,response): print("Md1返回") return responseclass Md2(MiddlewareMixin): def process_request(self,request): print("Md2请求") #return HttpResponse("Md2中断") def process_response(self,request,response): print("Md2返回") return response
第三步:在view中定义一个视图函数
def index(request): print("view函数...") return HttpResponse("OK")
第四步:在setting.py的MIDDLEWARE里注册自己定义的中间件
结果:
Md1请求Md2请求view函数...Md2返回Md1返回
注意:如果当请求到达请求2的时候 直接不符合条件返回,即return HttpResponse(‘MD2中断’),程序将把请求直接发给中间件2返回,然后依次 返回到请求者,结果如下 :
返回Md2中断 的页面,后台打印如下:
Md1请求Md2请求Md2返回Md1返回
流程图 如下 :
总结:
1、中间件的process_request方法是在执行视图之前 执行的。
2、当前配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后一依次执行。
3、不同中间件之间传递的request都是同一个对象。
多个中间件中 的process_response的方法是按照MIDDLEWARE中的注册顺序倒序执行的,一个中间件中的process_request方法首先执行,而他的process_response方法最后执行 ,最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行的。
process_view
process_view(self, request, view_func, view_args, view_kwargs)
该方法有四个参数
request是HttpRequest对象。
view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)
view_args是将传递给视图的位置参数的列表.
view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。
Django会在调用视图函数之前调用process_view方法。
它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。
from django.utils.deprecation import MiddlewareMixinfrom django.shortcuts import HttpResponseclass 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): print("Md1view")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("Md2view")
结果如下:
Md1请求Md2请求Md1viewMd2viewview函数...Md2返回Md1返回
下图进行分析 上面的过程:
当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。