August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Django的中间件
发布:2020年10月22日 | 作者:augustrush | 阅读量: 967

中间件

中间件是Django请求/响应处理的钩子框架。它是一个轻量级的、低级的"插件"系统,用于全局改变Django的输入或输出。

中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。

我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。


广泛的使用场景

  • 登录认证,安全拦截
  • 日志记录,性能上报
  • 缓存处理,监控告警...


编写自己的中间件

自定义中间件有2种方法

  • 使用函数实现
  • 使用类实现


函数实现

定义一个中间件函数,然后返回一个可以被调用的中间件。

中间件函数需要接受一个可以调用的get_response对象。

返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个request对象参数,返回一个response对象。

def simple_middleware(get_response):

    # TODO 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。

    def middleware(request):

        # TODO 此处编写的代码会在每个请求处理视图前被调用。

        response = get_response(reqeust)

        # TODO 此处编写的代码会在每个请求处理视图之后被调用。

        return response

    return middleware


类实现

定义一个中间件类,需要实现__init__方法和__call__方法,需要初始化Django提供的get_response方法,接收request对象,返回一个response对象。可以是一个真实的视图,也可能是请求处理链中的下一个中间件。

class SimpleMiddleware:
    def __init__(self, get_response)
        self.get_response = get_response
        # TODO 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。

    def __call__(self, request)
        # TODO 此处编写的代码会在每个请求处理视图前被调用。

        response = self.get_response(request)

        # TODO 此处编写的代码会在每个请求处理视图之后被调用。

        return response

Django实现了一个Middleware装饰器,在django.utils.deprecation.MiddlewareMixin

其源码:

class MiddlewareMixin(object):
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()

    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

用类实现中间件时,只需要继承MiddlewareMixin,然后实现process_requestprocess_response方法。

class MyMiddleware(MiddlewareMixin):
    def __init__(get_response):
        super(MyMiddleware, self).__init__(get_response)
        print('初始化执行且执行一次')

    def process_request(self, request):
        print('视图函数处理之前执行')

    def process_response(self, request, response):
        print('视图函数处理之后执行')
        return response

例如:在apps应用中新建一个middleware.py文件:

def my_middleware(get_response):
    print('只在初始化时执行一次。。。')

    def middleware(request):
        print('before request 时被调用。。。')
        response = get_response(request)
        print('after request 时被调用。。。')
        return response

    retrun middleware

定义好中间件后,需要在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',
    'apps.middleware.my_middleware', # 添加中间件
]

定义一个视图进行测试

def demo_view(request):
    print('view 视图被调用')
    return HttpResponse('ok')

执行结果

注意:Django运行在调试模式下,中间件init部分有可能被调用两次。


多个中间件的执行顺序

  • 在请求视图被处理前,中间件由上而下依次执行
  • 在请求视图被处理后,中间件由下而上依次执行

例如:

定义两个中间件

def my_middleware(get_response):
    print('init 被调用')
    def middleware(request):
        print('before request 被调用')
        response = get_response(request)
        print('after response 被调用')
        return response
    return middleware

def my_middleware2(get_response):
    print('init2 被调用')
    def middleware(request):
        print('before request 2 被调用')
        response = get_response(request)
        print('after response 2 被调用')
        return response
    return 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',
    'users.middleware.my_middleware',  # 添加
    'users.middleware.my_middleware2',  # 添加
]

执行结果

init2 被调用
init 被调用
before request 被调用
before request 2 被调用
view 视图被调用
after response 2 被调用
after response 被调用
上一篇:入坑Redis 下一篇:MySQL基本使用


  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed