Django 详解 中间件Middleware

Posted wuzdandz

tags:

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

Django中间件

还是涉及到django的请求生命周期。middle ware 请求穿过中间件到达url,再经过中间件返回给用户。

简单实例

django项目根目录新建一个Middle文件夹,再新建一个test.py文件

技术分享图片

在test文件中写入;其中的类必须继承 from django.utils.deprecation import MiddlewareMixin

from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
    def process_request(self, request):
        print(m1)
    def process_response(self, request, response):
        print(m1_r)
        return response


class M2(MiddlewareMixin):
    def process_request(self, request):
        print(m2)
    def process_response(self, request, response):
        print(m2_r)
        return response


class M3(MiddlewareMixin):
    def process_request(self, request):
        print(m3)

    def process_response(self, request, response):
        print(m3_r)
        return response

 

将你的测试中间件加入Django的中间件配置中,settings文件

技术分享图片

随便建一组对应路由。

技术分享图片

在index函数里面写上

def index(request):
    print(‘到达‘)
    return HttpResponse(‘ok‘)

查看结果:

技术分享图片

此时如果给某个中间件的process_request返回一个HttpResponse:

#!/user/bin/env python
# -*-coding: utf-8-*-
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class M1(MiddlewareMixin):
    def process_request(self, request):
        print(‘m1‘)
    def process_response(self, request, response):
        print(‘m1_r‘)
        return response


class M2(MiddlewareMixin):
    def process_request(self, request):
        print(‘m2‘)
        return HttpResponse(‘中断‘)  # 这里返回
    def process_response(self, request, response):
        print(‘m2_r‘)
        return response


class M3(MiddlewareMixin):
    def process_request(self, request):
        print(‘m3‘)

    def process_response(self, request, response):
        print(‘m3_r‘)
        return response

查看下结果

技术分享图片

技术分享图片

技术分享图片

可能你好像懂了,但是并没有,真正的中间件过程其实还有一个process_view.

技术分享图片View Code

技术分享图片

技术分享图片

自定制中间件的另一种方式

下面是最新的django2.1文档内的自定制中间件的另一种写法。

一个中间件工厂是可以被调用的,它接收一个可调用的get_response方法并返回一个中间件。中间件也是可调用的,它接收请求并返回响应,就像一个view视图

def simple_middleware(get_response):
    # 一次性配置和初始化

    def middleware(request):
        # 在每个请求之前被执行的代码
        #这个视图(和后面的中间件)被调用

        response = get_response(request)

        # 在每个请求或者响应之后代码被执行
        # the view is called.

        return response

    return middleware

或者他也可以被重写成一个实例可以被调用的类,像这个:

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # 一次性配置和初始化

    def __call__(self, request):
        # 在每一次请求之前代码被执行
        # 视图或者接下来的中间件被调用
        response = self.get_response(request)

        # 在每个请求或者响应之后代码将会被执行
        # the view is called.

        return response

可调用的get_response是由django提供的,可以是真实的视图函数或者也可以是链上的下一个中间件。当前的中间件不需要具体精确地知道或者关心它是什么,只是它代表接下来执行(到来的)是什么。

上面是一个小小的简化,可调用的get_response如果在中间件的最后一位,将不会是一个真实的视图函数,更可能是处理的一个外部包装方法,它关注于应用视图中间件,调用视图和合适的URL参数,并且使用template和exception中间件.

中间件可以生存在你的Python路径的任何地方。

 

__init__(get_response)

中间件工厂必须接收一个get_response参数,你也可以为中间件初始化一些全局的状态。记住下面的这几点

1、django只能使用get_response参数来初始化你的中间件,所以你不能定义__init__()来需要其他的参数

2、跟__call__()方法每次请求被调用不同,__init__()方法只会被调用一次,当web服务启动的时候

例如

class LoginMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    @method_decorator(adminlogin)
    def __call__(self, request):
        if request.method == "PUT":
            request.data = dict(urllib.parse.parse_qsl(request.body.decode()))
            request.data.update(request.GET.dict())
        elif request.method == "POST":
            request.data = request.POST.copy().dict()
        response = self.get_response(request)
        return response

详情请查阅django(version2.1)文档:https://docs.djangoproject.com/en/2.1/topics/http/middleware/

 

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

Django中Middleware中间件

Django组件之Middleware

Django 中间件 Middleware

django之(中间件)middleware

django之中间件middleware

利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击