中间件

Django中具有请求响应拦截功能的组件被称为中间件(Middleware),中间件可以在请求到达视图函数之前和响应返回客户端之前执行一些额外操作,中间件实现了面向切面编程(AOP),我们可以通过它实现登录拦截、请求预处理、安全检查等各种功能。

自定义中间件

Django 有许多内置中间件,不过我们这里还是先学习如何自定义一个中间件。下面是一个最简单的中间件例子。

demo01/middlewares.py

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

    def __call__(self, request):
        print('before processing request')
        response = self.get_response(request)
        print('after processing request')
        return response

代码中,response = self.get_response(request)是视图组件执行的流程,我们可以在其执行前和执行后做一些处理。其中,构造函数__init__()中可以编写中间件的初始化代码,__call__()中如果返回response,就代表整合 HTTP 的请求流程正常执行,如果需要重定向等操作,也可以返回HttpResponseRedirect()等响应。

编写好中间件类后,我们还需要在settings.py中配置并引入它。

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',
    # 自定义中间件
    'demo01.middleware.MyMiddleware'
]

此处如果引入了一个不存在的中间件,Django启动将报错。

中间件 URL 匹配模式

Django中,中间件本身并不直接提供URL匹配模式的设置,但我们能在__call__中获取request对象,一种办法是手动进行请求URL匹配,request.path就是本次请求的路径,我们可以基于该属性进行判断。

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

    def __call__(self, request):
        if request.path and request.path.startswith('/media/'):
            print('before processing request to /media/')
        response = self.get_response(request)
        return response

代码中,我们的中间件仅匹配/media/为前缀的URL,不满足条件的请求将不会被该中间件处理。

内置中间件

Django其实本身就包含了很多内置中间件,下面简单列出了一些常用的内置中间件。

中间件 功能描述
SecurityMiddleware 提供安全相关的功能,如HTTP头部设置,防止跨站请求伪造等。
SessionMiddleware 处理会话数据,提供会话管理支持。
AuthenticationMiddleware auth模块提供,处理用户认证,提供request.user对象。
MessageMiddleware 处理一次性消息的存储与检索,通常用于用户通知。
CsrfViewMiddleware 提供跨站请求伪造保护,验证CSRF令牌。
CommonMiddleware 提供常见的功能,如处理Content-LengthContent-Type
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。