码迷,mamicode.com
首页 > 其他好文 > 详细

22)django-中间件

时间:2017-11-13 23:15:14      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:click   options   error   net   nbsp   测试   五个   顺序   quit   

一:中间件介绍

  django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,

  django会根据自己的规则在合适的时机执行中间件中相应的方法。

  在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件。示例

settings.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,
]

 

二:中间件执行顺序

  中间件执行顺序是:请求(process_request)时候是从上到下顺序执行,返回(process_response)是下到上执行。

  示例图如下:

技术分享

 

  中间件中可以定义五个方法,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

  以上方法的返回值可以是None和HttpResonse对象,如果是None,

  则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

 

三:自定义中间件

  结合上面的5个方法观察中间件执行顺序。

  自定义中间件需要继承:from django.utils.deprecation import MiddlewareMixin

  1)process_request方法执行顺序

  创建文件middle.m1.py

    #middle.m1.py
        # -*- coding:utf-8 -*-
        __author__ = shisanjun
        from django.utils.deprecation import MiddlewareMixin
        class Row1(MiddlewareMixin):
        
            def process_request(self,request): #这就表示写了个中间件了
                print(111)

        class Row2(MiddlewareMixin):
        
            def process_request(self,request): #这就表示写了个中间件了
                print(222)

        class Row3(MiddlewareMixin):
        
            def process_request(self,request): #这就表示写了个中间件了
                print(3333)

  上面创建三个中间件,还需要在settings.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,
    ‘middle.m1.Row1‘,
    ‘middle.m1.Row2‘,
    ‘middle.m1.Row3‘,
]

  测试views.py  

def test(request):
    int("aaa")
    print("小姨妈")
    return HttpResponse("ok")

  urls.py 

 url(r^test/, views.test),

  测试结果: 

    #结果
    ======================================
    111
    222
    3333
    小姨妈

  执行顺序

  技术分享

 

  2)中间件里有process_response(self, request, response),此方法需要返回return response,否则报错。

  

    __author__ = shisanjun
    from django.utils.deprecation import MiddlewareMixin
    class Row1(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(111)
    
        def process_response(self,request,response):
            pass
    
    class Row2(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(222)
        def process_response(self,request,response):
            pass
    
    class Row3(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(3333)
        def process_response(self,request,response):
            pass


    报错:这说明views有返回值,但是中间件没有取,process_response没有做处理,需要返回response
    AttributeError at /test/
    NoneType object has no attribute get

   修改如下:

修改:
    # -*- coding:utf-8 -*-
    __author__ = shisanjun
    from django.utils.deprecation import MiddlewareMixin
    class Row1(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(111)
    
        def process_response(self,request,response):
            print("到1了")
            return response
    
    class Row2(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(222)
        def process_response(self,request,response):
            print("到2了")
            return response
    
    class Row3(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(3333)
        def process_response(self,request,response):
            print("到3了")
            return response

  结果:

  

    #结果
    Quit the server with CTRL-BREAK.
    111
    222
    3333
    小姨妈
    到3了
    到2了
    到1了

  执行顺序:

  技术分享

    这里request和response就是view中的,所以request含有所有HTTP请求
    
    中间有什么用了?
    可以在中间件做一些判断,比如在中间件判断是不是有请求头,如果没有就不让往后面走(可以直接return HttpResponse)


    django,在1.10版本中在那个中间件返回,就从那个返回。
    在1.7,1。8版本中不是,是在中间的中间件要求返回,但是还是会走到最后一个中间,再返回。

    中间件适合什么操作了?对所有请求做统一的操作。

 

  3)中间件里有process_view(self,request,view_func,view_args,view_kwargs):。

# -*- coding:utf-8 -*-
    __author__ = shisanjun
    from django.utils.deprecation import MiddlewareMixin
    class Row1(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(111)
    
        def process_view(self,request,view_func,view_args,view_kwargs):
            print("中间1")
    
        def process_response(self,request,response):
            print("到1了")
            return response
    
    class Row2(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(222)
        def process_view(self,request,view_func,view_args,view_kwargs):
            print("中间2")
        def process_response(self,request,response):
            print("到2了")
            return response
    
    class Row3(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(3333)
        def process_view(self,request,view_func,view_args,view_kwargs):
            print("中间3")
        def process_response(self,request,response):
            print("到3了")
        return response

    #结果
    Quit the server with CTRL-BREAK.
    111
    222
    3333
    中间1
    中间2
    中间3
    小姨妈
    到3了
    到2了
    到1了
    
    
    view_func就是view函数

 顺序

  技术分享

   4)中间件里有process_exception(self, request, exception)

  

    class Row3(MiddlewareMixin):
    
        def process_request(self,request): #这就表示写了个中间件了
            print(3333)
        def process_view(self,request,view_func,view_args,view_kwargs):
            print("中间3")
        def process_response(self,request,response):
            print("到3了")
            return response
        def process_exception(self, request, exception):#当view出错的时候执行
            print("err")


    比如
    def test(request):
        int("aaa")#这里转换为整数,会报错,就会调用上面的process_exception
        print("小姨妈")
        return HttpResponse("ok")

  5)中间件里有process_template_response(self,request,response)

  

class Row3(MiddlewareMixin):

    def process_request(self,request): #这就表示写了个中间件了
        print(3333)
    def process_view(self,request,view_func,view_args,view_kwargs):
        print("中间3")
    def process_response(self,request,response):
        print("到3了")
        return response
    def process_exception(self, request, exception):#什么时候执行了,当views函数出错了,就执行了
        if isinstance(exception,ValueError):
            print(9999)

    def process_template_response(self,request,response):
        #如果views中的函数返回对象中,具有render方法,就会执行。
        print("process_template_response")

 

22)django-中间件

标签:click   options   error   net   nbsp   测试   五个   顺序   quit   

原文地址:http://www.cnblogs.com/lixiang1013/p/7828348.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!