zoukankan      html  css  js  c++  java
  • 二、中间件(middleware)

    1.      中间件(middleware)

    Django中的中间件主要实现一些附加功能,在request被用户handler处理前,以及用户handler处理后生存的response进行处理。因此大部分中间件的主要功能是实现了process_request或者process_response之一,当然也可以两者都实现,意味着该中间件涉及到处理的request和response的处理。

    1.1       类视图

    在中间件的类关系中,基本类是MiddlewareMixin,其他所有的中间件类都继承自该类,该类仅有一个成员变量get_response,该变量在连接各个中间件起着非常重要的作用。该类有两个成员函数:__init__和__call__,前者用于实现初始化,后者执行主要的功能。

        def __call__(self, request):

            response = None

            if hasattr(self, 'process_request'):

                response = self.process_request(request)

            if not response:

                response = self.get_response(request)

            if hasattr(self, 'process_response'):

                response = self.process_response(request, response)

            return response

    其中process_request和process_response自不必多言,中间件需要实现的主要功能,通过hasattr()调用,判断当前中间件是否具有process_request和process_response,有则调用。

    不同功能的中间件,根据要完成的功能,可以扩展自己的成员变量和成员函数,通常,自定义的成员函数被process_request和process_response调用,即这些自定义的成员函数通常不对外开放。

           其中,__init__成员函数有入参函数之一: get_response,这在后续的加载中间件时很重要好。

    下图是中间件SecurityMiddleware类的类视图关系图,其他中间件的视图关系类似。

     

    1.2       中间件初始化

    在工程的配置文件(Project/Project/setting.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',

    ]

    下面来看,中间件是如何被加载和初始化的。class BaseHandler(object):中定义了load_middleware接口,具体细节如下:

    handler = convert_exception_to_response(self._get_response)  /*handler[0]*/

    for middleware_path in reversed(settings.MIDDLEWARE):
        middleware = import_string(middleware_path)

        mw_instance = middleware(handler)
        handler = convert_exception_to_response(mw_instance) /*handler[i]*/
    self._middleware_chain = handler                    /*handler[end]*/

    在上述例程中,开始遍历所有中间件之前,handler(即handler[0])赋值给调用实体的_get_response成员函数。                   (比如class WSGIHandler(base.BaseHandler),WSGIHandler. load_middleware()调用之后,handler[0] = WSGIHandler._get_response = BaseHandler._get_response())。遍历所有中间件过程中,加载并初始化(middleware()调用对应着__init__成员函数)中间件,因此中间件的get_response赋值为handler[i],注意middleware()返回一个中间件类实体,接着调用调用handler  = convert_exception_to_response (mw_instance),convert_exception_to_response只是对输入函数进行了容错封装,在分析逻辑时,可以简单看成输入函数本身,因此,可以看成handler = mw_instance(request),对于一个类实体调用即调用__call__成员函数,从目前来看,大部分的中间件并没有重载该成员函数,因此是直接调用基类的成员函数,即: MiddlewareMixin. __call__(self)。因此handler[i] = MiddlewareMixin. __call__(self)。注意该函数有一个self输入参数,各个中间件在调用时,传入该中间件对应的self实体,这样self.process_request, self.process_response的调用就分别对应着不同中间夹的处理函数。load_middleware()调用之后,各个中间件通过get_response链接起来,这样一个request请求到来时,可以顺序通过各个中间件依次进行处理,如下图所示:

     

    在调用的最后,将self._middleware_chain = handler[end],类似于将中间件链表的链表头保存起来,下次处理时,从该链表头开始进行遍历处理。

    1.3       中间件使用

    各个中间件的调用顺序如下递归图所示:

     

    在类视图一节中对__call__基类成员函数进行过介绍,该函数主要有先后执行的三个函数构成:process_request()、get_response()、process_response(),而get_response()通常指向下一个中间件的__call__成员函数(中间件链表的最后一个中间件除外,其get_response()指向handler[0]),由于各个中间件的get_response()这一特性(绝大部分指向基类__call__成员函数),使得中间件链表处理有点类似递归调用的感觉。A,B,A1,B1,A2,B2,C2,C1,C,这一递归调用顺序,决定了各个中间件处理的一些特点:

    1、最先进行流程处理的中间件,其process_request()(如果存在的话)最先被执行,但是其process_response()(如果存在的话)却最后得到处理。

    2、最后进行流程处理的中间件,其process_request()(如果存在的话)最后被执行,但是其process_response()(如果存在的话)紧接着得到处理。

    3、在中间件处理流程中,如果出现某个中间件的process_request()返回了response,这种情况通常是处理过程中出现了异常情况,该中间件后续的中间件不再参与处理,直接调用该中间件的process_response()(如果存在的话),或者直接返回。

  • 相关阅读:
    LCD编程_显示文字
    LCD编程_画点线圆
    LCD编程_简单测试
    LCD编程框架组织
    LCD编程_LCD控制器
    编程——抽象出重要的结构体
    LCD裸板编程_框架
    S3C2440_LCD控制器
    关于加密与解密的问题。
    [13期]mysql-root全手工注入写马实例实战
  • 原文地址:https://www.cnblogs.com/fbli/p/5925071.html
Copyright © 2011-2022 走看看