python之路_django中间件

  中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。django中自带如下7个中间件,在setting配置可见,如下:

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',

]

一、自定义django中间件

  除了django自带如上7种中间件,我们为了满足自己的需求,也可自定义中间件,中间件就是定义一个类,类的下面有四个方法,分别为process_request、process_view、process_exception及process_response,但此类必须但是必须继承MiddlewareMixin,引入方式如下:from django.utils.deprecation import MiddlewareMixin

  自定义中间件实例如下,中间件.py文件必须放在django项目的根目录下,中间件的配置方式与自带中间件配置方式一致。如下实例:

二、中间件执行顺序

1、中间件被执行的顺序

  如上,中间件的执行顺序是按照如上中间件配置顺序执行的,从上到下,依次执行中间件中的process_request函数,然后根据url执行所有views视图函数,视图函数执行完后,再从后依次往前执行process_response函数。

  但是需要注意,如下为请求的视图函数和自定义的中间件:

views函数:

def index(request):
    print("view函数...")
    return HttpResponse("OK")

中间件:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class Md1(MiddlewareMixin):

    def process_request(self,request):
        print("Md1请求")
        #return HttpResponse("Md1中断")
    def process_response(self,request,response):
        print("Md1返回")
        return response

class Md2(MiddlewareMixin):

    def process_request(self,request):
        print("Md2请求")
    def process_response(self,request,response):
        print("Md2返回")
        return response

  此时输出结果顺序为:

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

  但是当把#return HttpResponse("Md1中断")的注释释放,即 process_request请求有返回值时,中间件便不会继续往下走了,视图函数也不会再被执行,会原路返回以上的process_response,次点值得广大读者的注意,这也是自定义中间件一个主要应用点,执行结果为:

Md1请求
Md1返回

二、中间件中的函数执行顺序

  如上为中间件的总体执行顺序,但是当中间件中还有process_view和process_exception时,中间件内部函数的总体执行顺序又如何呢?如下为自定义中间件文件及要请求的视图函数:

1、process_view情况

中间件:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

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):
        print("Md1view")

class Md2(MiddlewareMixin):

    def process_request(self,request):
        print("Md2请求")def process_response(self,request,response):
        print("Md2返回")
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("Md2view")

views函数:

def index(request):

    print("view函数...")
    return HttpResponse("OK")

  请求后执行的结果为:

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

  由上知道,中间件函数的执行顺序分析图如下:

  如上,顺序为:当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。

  process_view可以用来调用视图函数:

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

  结果为:

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

  注意:process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行。

 2、process_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返回

  由上可见,process_exception函数并没有没执行,为什么呢?因为此函数的是views函数执行出错时候,或者某一个中间件中此函数有返回值时才会被执行,但并不影响这四个函数的总体执行顺序,顺序分析如下:

 

posted @ 2017-12-29 17:31  骑猪走秀  阅读(156)  评论(0编辑  收藏  举报