中间件的概念

  中间件其实就是介于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")
views中代码

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
自定义中间件,Mymiddlewares.py

将中间件文件创建在根目录:

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',       
]
setting中的中间件

运行结果:

Md1请求
Md2请求
view函数...
Md2返回
Md1返回

 如果将里面注释的请求二中的return HttpResponse取消注释,也就是如果请求到达请求2不符合条件是程序将请求直接发给中间件2返回:

结果:

Md1请求
Md2请求
Md2返回
Md1返回

 process_view:

process_view(self, request, callback, callback_args, callback_kwargs)
修改版(给两个中间件都加上process_view)

结果:

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...")
给中间件加上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返回

  

 

  

 

posted on 2018-03-06 20:04  无痕5201314  阅读(161)  评论(0编辑  收藏  举报