中间件

Posted xiaole-7890

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中间件相关的知识,希望对你有一定的参考价值。

1、什么是中间件?

中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是以轻量级,低级别的插件系统、用于在全局内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

但是由于其影响的是全局,所以需要谨慎使用,使用不到会影响性能。

说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

2、MIDDLEWARE(中间件)配置项

MIDDLEWARE = [
  
django.middleware.security.SecurityMiddleware‘,
  ‘django.contrid.sessions.middleware.SessionMiddleware‘,
  ‘django.middleware.common.CommonMiddleware‘,
  ‘django.middleware.csrf.CsrfViewMiddleware‘,
  ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,
  ‘django.contib.messages.middleware.MessageMiddleware;,
  ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘,
] 

3、自定义中间件

中间件可以定义五个方法,分别是:(主要的process_request和process_response)

  (1)process_request(self,request)

  (2)process_view(self,request,view_func,view_args,view_kwargs)

  (3)process_template_response(self,request,response)

  (4)process_exception(self,request,exception)  

  (5)process_response(self,request,response)

以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

自定义一个中间件示列

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response

process_request

pprocess_request有一个参数,就是request,这个request和视图函数中的request是一样的。

它的返回值可以是None也可以是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,如果是HttpResponse对象,Django将执行shitu函数,而将相应对象返回给浏览器。

Django是如何执行其中的process_request方法的

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

在settings.py的MIDDLEWARE配置项中注册上述两个自定义中间件:

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,
    middlewares.MD1,  # 自定义中间件MD1
    middlewares.MD2  # 自定义中间件MD2
]

此时,我们访问一个视图,会发现终端打印如下内容:

MD1里面的 process_request
MD2里面的 process_request
app01 中的 index视图

把MD1和MD2的位置调换一下,在访问一个视图,会发现终端中打印的内容如下:

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index视图

总结:

  1.中间件的process_request方法是在执行视图函数之前执行

  2.当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。

  3.不同中间件之间传递的request都是不同一个对象。

多个中间件中的process_respose方法是按照MIDDLEWARE中的注册顺序大圩执行的,第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_response方法最后一个执行,它的process_response方法是最先执行。

process_response

它有两个参数,一个是request,一个是response,request就是上述列子中一样的对象,response是视图函数返回的HttpReaponse对象。该方法的返回值也必须是HttpResponse对象。

给上述的M1和M2加上process_response方法:

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

    def process_response(self, request, response):
        print("MD2里面的 process_response")
        return response

访问一个视图,终端输出:

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index视图
MD1里面的 process_response
MD2里面的 process_response

多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,也就是说第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_request方法最后一个执行,它的process_reponse方法是最先执行。

process_view

process_view(self,view_func,view_args,view_kwargs)

该方法有四个参数

request是HttpRequest对象。

view_func是Django即将使用的视图函数(它是实际的函数对象,而不是函数的名称作为字符串。)

view_args是将传递给视图的位置参数的列表。

 

 











以上是关于中间件的主要内容,如果未能解决你的问题,请参考以下文章

Sublime Text3自定义代码片段

无法更新 View Pager 中的中间片段。

Android - 从堆栈中间删除特定片段不起作用

从没有中间转换变量的片段中观察 ViewModel LiveData

如何将数据从顶点着色器传递到片段着色器,中间有着色器[重复]

如何定义对话框片段的重力?