跳转至

Django中间件

Django 中间件是处理请求和响应的钩子,它们可以在每个请求到达视图之前、视图处理后和响应返回浏览器之前执行一些处理逻辑。中间件在整个请求/响应周期中非常有用,可以用来实现各种功能,如用户认证、请求日志、性能监控、内容压缩等。

如何编写自定义中间件

编写一个简单的中间件包括以下步骤:

  1. 创建一个中间件类。
  2. 在中间件类中定义请求处理方法。
  3. 将中间件类添加到 Django 项目的中间件设置中。

示例:编写和使用自定义中间件

1. 创建中间件类

首先,在你的 Django 应用程序中创建一个新的文件,例如 middleware.py,然后定义一个中间件类。每个中间件类至少应该实现以下一个或多个方法:

  • __init__(self, get_response): 每个请求/响应生命周期只调用一次,用于中间件的初始化。
  • __call__(self, request): 在中间件处理请求时调用。
  • process_request(self, request): 在视图处理请求之前调用。
  • process_view(self, request, view_func, view_args, view_kwargs): 在 Django 调用视图之前调用。
  • process_exception(self, request, exception): 在视图抛出异常时调用。
  • process_response(self, request, response): 在视图处理请求之后、响应返回之前调用。

下面是一个简单的示例中间件,记录请求处理时间:

# myapp/middleware.py

import time
from django.utils.deprecation import MiddlewareMixin

class SimpleMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.start_time = time.time()

    def process_response(self, request, response):
        duration = time.time() - request.start_time
        response['X-Request-Duration'] = str(duration)
        return response

2. 添加中间件到设置中

接下来,需要将自定义中间件添加到 Django 项目的中间件设置中。打开你的项目的 settings.py 文件,找到 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',
    'myapp.middleware.SimpleMiddleware',  # 添加自定义中间件
]

其他常见的中间件

用户认证中间件

Django 内置了用户认证中间件,用于处理用户的认证状态:

# settings.py

MIDDLEWARE = [
    ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    ...
]

CSRF 保护中间件

Django 提供了防止跨站请求伪造 (CSRF) 的中间件:

# settings.py

MIDDLEWARE = [
    ...
    'django.middleware.csrf.CsrfViewMiddleware',
    ...
]

请求和响应压缩中间件

Django 也提供了用于压缩请求和响应内容的中间件:

# settings.py

MIDDLEWARE = [
    ...
    'django.middleware.gzip.GZipMiddleware',
    ...
]

中间件的执行顺序

Django 中间件按顺序在 MIDDLEWARE 列表中列出,并按照以下规则执行:

  1. 请求处理顺序
  2. 在处理请求时,从 MIDDLEWARE 列表的最上方开始,依次调用每个中间件的 __call__process_request 方法,直到最底部。

  3. 响应处理顺序

  4. 在处理响应时,从 MIDDLEWARE 列表的最底部开始,依次调用每个中间件的 __call__process_response 方法,直到最上方。

请求处理顺序示例

假设有以下中间件配置:

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

请求处理顺序如下:

  1. SecurityMiddleware
  2. SessionMiddleware
  3. CommonMiddleware
  4. CsrfViewMiddleware
  5. AuthenticationMiddleware
  6. MessageMiddleware
  7. XFrameOptionsMiddleware
  8. SimpleMiddleware

响应处理顺序示例

响应处理顺序与请求处理顺序相反,从下到上:

  1. SimpleMiddleware
  2. XFrameOptionsMiddleware
  3. MessageMiddleware
  4. AuthenticationMiddleware
  5. CsrfViewMiddleware
  6. CommonMiddleware
  7. SessionMiddleware
  8. SecurityMiddleware

中间件执行顺序的实际应用

下面是一个示例中间件,用于演示请求和响应处理顺序:

# myapp/middleware.py

from django.utils.deprecation import MiddlewareMixin

class FirstMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('FirstMiddleware: process_request')

    def process_response(self, request, response):
        print('FirstMiddleware: process_response')
        return response

class SecondMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('SecondMiddleware: process_request')

    def process_response(self, request, response):
        print('SecondMiddleware: process_response')
        return response

settings.py 中添加中间件:

# settings.py

MIDDLEWARE = [
    ...
    'myapp.middleware.FirstMiddleware',
    'myapp.middleware.SecondMiddleware',
    ...
]

当一个请求到达服务器时,控制台将打印以下内容:

FirstMiddleware: process_request
SecondMiddleware: process_request

当响应被返回给客户端时,控制台将打印以下内容:

SecondMiddleware: process_response
FirstMiddleware: process_response

中间件中的异常处理

中间件还可以处理视图函数中抛出的异常,通过 process_exception 方法来实现。异常处理的执行顺序与响应处理顺序相同,从最底部的中间件开始,依次向上处理。

示例:

# myapp/middleware.py

class ExceptionMiddleware(MiddlewareMixin):
    def process_exception(self, request, exception):
        print(f'ExceptionMiddleware: {exception}')

settings.py 中添加中间件:

# settings.py

MIDDLEWARE = [
    ...
    'myapp.middleware.ExceptionMiddleware',
    ...
]

当视图函数抛出异常时,控制台将打印异常信息:

ExceptionMiddleware: <异常信息>

总结

中间件是 Django 请求/响应处理周期中的关键部分,允许开发者在请求到达视图之前或响应返回客户端之前进行处理。通过编写自定义中间件,你可以实现各种功能,如日志记录、性能监控、认证和授权等。在编写中间件时,需要注意性能影响,尽量确保中间件的处理逻辑高效且无副作用。

评论