Django 自定义中间件

好的,我给你一个 Django 自定义中间件的完整示例,包含说明和注册方式。中间件可以用来处理请求和响应,比如日志记录、请求计时、权限检查等。


1️⃣ 创建自定义中间件文件

假设你的 app 名为 myapp,在 myapp/middleware.py 中创建:

# myapp/middleware.py
import time
from django.utils.deprecation import MiddlewareMixin

class TimerMiddleware(MiddlewareMixin):
    """
    一个示例中间件,用于统计请求处理时间
    """

    def process_request(self, request):
        """
        请求到达视图前调用
        """
        request.start_time = time.time()
        print(f"[TimerMiddleware] 请求路径: {request.path} 开始计时")
        # 可以返回 HttpResponse 来中断请求
        # return HttpResponse("请求被中间件拦截")

    def process_response(self, request, response):
        """
        视图处理完后调用
        """
        duration = time.time() - getattr(request, 'start_time', time.time())
        print(f"[TimerMiddleware] 请求路径: {request.path} 处理时间: {duration:.2f}s")
        return response

    def process_exception(self, request, exception):
        """
        视图抛出异常时调用
        """
        print(f"[TimerMiddleware] 请求路径: {request.path} 出现异常: {exception}")
        # 返回 None 让 Django 继续处理异常
        return None

⚠️ 注意:

  • MiddlewareMixin 在 Django 2.x/3.x/4.x 都可用,它封装了老式的 process_requestprocess_response 等方法。
  • Django 1.10+ 也支持新的中间件风格,即只实现 __init____call__

2️⃣ 注册中间件

settings.py 中的 MIDDLEWARE 列表里加入:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # ... 其他中间件
    'myapp.middleware.TimerMiddleware',  # 我们的自定义中间件
]

中间件的顺序很重要,Django 会按照列表顺序执行 process_request,然后反向执行 process_response


3️⃣ 使用示例

访问任意视图,你会在控制台看到类似:

[TimerMiddleware] 请求路径: /home/ 开始计时
[TimerMiddleware] 请求路径: /home/ 处理时间: 0.01s

如果视图抛出异常,也会打印:

[TimerMiddleware] 请求路径: /home/ 出现异常: ZeroDivisionError('division by zero')

4️⃣ 新式中间件写法(Django 1.10+)

# myapp/middleware.py
import time

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

    def __call__(self, request):
        start_time = time.time()
        response = self.get_response(request)
        duration = time.time() - start_time
        print(f"[TimerMiddlewareNew] {request.path} 耗时: {duration:.2f}s")
        return response
  • 优点:更符合现代 Django 风格。
  • 注册方式一样。

你希望我写吗?

Scroll to Top