中间件之原理、作用、自定义、注册、流程

中间件

位置:django请求生命周期的用户请求之后,路由系统之前

其它语言或web框架,又称之为管道、HttpHandler

原理

所有的请求都必须穿过中间件,到达业务逻辑,业务处理完成后,再通过中间件,返回给用户

django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

作用

  • 用户请求数据,判定
  • 整体业务运行前的判定工作,例如黑名单

自定义

在工程目录下,创建文件夹,文件夹名任意,例如Middle

Middle下可以嵌套文件夹,也可以直接写python程序,文件名任意,例如m1.py

from django.utils.deprecation import MiddlewareMixin
import inspect


class Row1(MiddlewareMixin):
    def process_request(self, request):
        print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))

    def process_view(self, request, view_func, view_func_args,
                     view_func_kwargs):
        print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))

    def process_response(self, request, response):
        print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
        return response

	def process_exception(self, request, exception):
        print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
        if isinstance(exception, ValueError):
            return HttpResponse('出现异常')

    def process_template_response(self, request, response):
        # 如果Views中的函数返回的对象中,具有render方法
        print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
        return response

注:类中的方法名,不能变;process_response方法的参数request, response的顺序也不能变

注:至少掌握process_request、process_view、process_response方法

注册

工程的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',
]

流程

process_request -》 路由匹配——》process_view-》业务逻辑-》process_reponse

Row1.process_request
Row2.process_request
Row3.process_request
Row1.process_view
Row2.process_view
Row3.process_view
views.py middle
Row3.process_response
Row2.process_response
Row1.process_response

若路由匹配失败

Row1.process_request
Row2.process_request
Row3.process_request
Row3.process_response
Row2.process_response
Row1.process_response
Not Found: /middle/

若process_request存在返回,django版本1.10的如下:

class Row2(MiddlewareMixin):
    def process_request(self, request):
        print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
        return HttpResponse('go out')

Row1.process_request
Row2.process_request
Row2.process_response
Row1.process_response

业务逻辑,异常时,执行process_exception

def middle(request):
    import inspect
    int('aaa')
    print('views.py %s' % inspect.stack()[0][3])
    return HttpResponse('ok')

Row1.process_request
Row2.process_request
Row3.process_request
Row1.process_view
Row2.process_view
Row3.process_view
Row3.process_exception
Row3.process_response
Row2.process_response
Row1.process_response

如果views.py中的函数返回的对象中,具有render方法,

则执行process_template_response


import inspect
class Foo:
    def render(self):
        print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
        return HttpResponse('ok')

def middle(request):
    print('views.py %s' % inspect.stack()[0][3])
    return Foo()


Row1.process_request
Row2.process_request
Row3.process_request
Row1.process_view
Row2.process_view
Row3.process_view
views.py middle
Row3.process_template_response
Row2.process_template_response
Row1.process_template_response
Foo.render
Row3.process_response
Row2.process_response
Row1.process_response
posted @ 2018-04-10 22:38  12兵哥哥  阅读(525)  评论(0编辑  收藏  举报