Django之中间件

一、什么是中间件

  请求和响应之间的一道屏障 

作用:控制请求和响应

Django默认的中间件 :(在django项目的setting模块中,有一个 MIDDLEWARE_CLASS变量,其中每一个元素就是一个中间件 )

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

每一个中间件都有具体的功能

二 、自定义中间件

中间件主要有几个方法:

-from django.utils.deprecation import MiddlewareMixin   先导入
            -定义一个类,随意命名,继承MiddlewareMixin
            class MyMiddleware1(MiddlewareMixin):
                def process_request(self, request):
                    print('MyMiddleware---->1---->process_request')
                    # 返回HttpRspons对象,直接返回,走自己的process_response
                    # 返回None的时候,继续往下走
                    # return HttpResponse('i am middle--1')
                    return None

                def process_response(self, request, response):

                    print('MyMiddleware--->1---->process_response')
                    return response
            -使用:在setting中注册,是有顺序的,
                MIDDLEWARE = [
                'app01.mymiddelware.MyMiddleware1',
                ]
            

中间件执行顺序:

  process_request,从上往下执行,

  如果return  HttpResponse的对象,直接返回了;

  如果return None,继续往下走

中间件的方法:

  process_request:请求来的时候,会响应它

  process_response:响应回去的时候,会走它

  process_view (了解): request, callback(视图函数), callback_args(无名分组的参数), callback_kwargs(有名分组的参数)

三、process_request和process_response

当用户发起请求的时候会依次经过所有的中间件,这个时候请求 procsee_request,最后到达 views的函数中,views函数处理后 ,在依次穿过中间件,这个时候是process_response,最后返回给请求者。

上述截图中的中间件都是Django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承MiddlewareMixin

第一步:导入

from` `django.utils.deprecation ``import` `MiddlewareMixin

第二步 :自定义中间件

  

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

class Md1(MiddlewareMixin):

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

class Md2(MiddlewareMixin):

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

第三步:在view中定义一个视图函数

def index(request):

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

第四步:在setting.py的MIDDLEWARE里注册自己定义的中间件

结果:

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

注意:如果当请求到达请求2的时候 直接不符合条件返回,即return HttpResponse(‘MD2中断’),程序将把请求直接发给中间件2返回,然后依次 返回到请求者,结果如下 :

返回Md2中断 的页面,后台打印如下:

Md1请求
Md2请求
Md2返回
Md1返回

流程图 如下 :

总结:

  1、中间件的process_request方法是在执行视图之前 执行的。

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

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

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

process_view 

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

该方法有四个参数

request是HttpRequest对象。

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

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

view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。

Django会在调用视图函数之前调用process_view方法。

它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。

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请求")
        return HttpResponse("Md2中断")
    def process_response(self,request,response):
        print("Md2返回")
        return response

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

结果如下:

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

下图进行分析 上面的过程:

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

posted @ 2018-11-23 19:07  薛才昌  阅读(228)  评论(0编辑  收藏  举报