烂蜻蜓头像
关注
Django入门教程(十七):中间件详解——请求响应处理管道与四大钩子方法封面图

Django入门教程(十七):中间件详解——请求响应处理管道与四大钩子方法

一、什么是中间件?

Django 中间件是修改 Django request 或者 response 对象的钩子,可以理解为介于 HttpRequest 与 HttpResponse 处理之间的一道处理过程

浏览器从请求到响应的过程中,Django 需要通过很多中间件来处理。

中间件的两大作用:

作用说明
修改请求修改传送到 view 中的 HttpRequest 对象
修改响应修改 view 返回的 HttpResponse 对象

典型应用场景:

  • 用户认证与权限校验

  • 请求日志记录

  • 跨域处理

  • 全站性能监控

  • 请求频率限制

二、Django 默认中间件配置

中间件组件配置在 settings.py 文件的 MIDDLEWARE 选项列表中。配置中的每个字符串选项都是一个类,也就是一个中间件。

python

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',
]

默认中间件功能说明:

中间件作用
SecurityMiddleware安全相关处理,如 HTTPS 重定向、安全头
SessionMiddleware启用 Session 支持
CommonMiddleware通用处理,如 URL 重定向、APPEND_SLASH
CsrfViewMiddleware提供 CSRF 保护
AuthenticationMiddleware为 request 添加 user 属性
MessageMiddleware启用消息框架
XFrameOptionsMiddleware防止点击劫持攻击

注意: MIDDLEWARE 的顺序非常重要,它决定了中间件的执行顺序。顺序错误可能导致功能异常。

三、自定义中间件的步骤
Step 1:在 app 目录下新建 py 文件

文件名可自定义,如 middlewares.py,并导入 MiddlewareMixin

python

from django.utils.deprecation import MiddlewareMixin
Step 2:定义中间件类

自定义的中间件类必须继承 MiddlewareMixin

python

class MD1(MiddlewareMixin):
    pass
Step 3:在 settings.py 中注册

python

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',

    'app01.middlewares.MD1',   # 注册自定义中间件
]

注册位置决定执行顺序: 越靠前的中间件,process_request 越先执行,process_response 越后执行。

四、中间件的四大方法

中间件可以定义四个方法:

方法执行时机
process_request(self, request)视图函数之前
process_view(self, request, view_func, view_args, view_kwargs)视图函数之前,process_request 之后
process_exception(self, request, exception)视图函数抛出异常时
process_response(self, request, response)视图函数之后
五、process_request 方法

签名: process_request(self, request)

参数: request,与视图函数中的 request 是同一个对象。

返回值:

  • None:按正常流程继续走,交给下一个中间件处理。

  • HttpResponse 对象:Django 将不执行后续视图函数之前的方法以及视图函数,直接以该中间件为起点,倒序执行中间件的 process_response 方法。

执行特点:

  • 在视图函数之前执行。

  • 多个中间件时,按 MIDDLEWARE 注册顺序顺序执行。

  • 不同中间件之间传递的 request 参数都是同一个请求对象

示例:

python

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request))   # 在视图之前执行

返回值对流程的影响:

六、process_response 方法

签名: process_response(self, request, response)

参数:

  • request:请求对象

  • response:视图函数返回的 HttpResponse 对象

返回值: 必须要有返回值,且必须是 response。

执行特点:

  • 在视图函数之后执行。

  • 多个中间件时,按 MIDDLEWARE 注册顺序倒序执行。

示例:

python

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request))

    def process_response(self, request, response):
        print("md1  process_response 方法!", id(request))   # 在视图之后
        return response

执行顺序示意:

text

请求 → MD1.process_request → MD2.process_request → 视图函数
     → MD2.process_response → MD1.process_response → 响应

如果 MD1 的 process_request 有返回值:

text

请求 → MD1.process_request(返回 HttpResponse) → MD1.process_response → 响应

后面的中间件和视图函数都不会执行。

七、process_view 方法

签名: process_view(request, view_func, view_args, view_kwargs)

参数:

  • request:HttpRequest 对象

  • view_func:Django 即将使用的视图函数

  • view_args:将传递给视图的位置参数列表

  • view_kwargs:将传递给视图的关键字参数字典

注意: view_args 和 view_kwargs 都不包含第一个视图参数(request)。

返回值:

  • None:按正常流程继续走,交给下一个中间件处理。

  • HttpResponse 对象:不执行后续视图函数之前的方法以及视图函数,直接以该中间件为起点,倒序执行 process_response

  • view_func(request):不执行后续视图函数之前的方法,提前执行视图函数,然后再倒序执行 process_response

执行特点:

  • 在视图函数之前process_request 方法之后执行。

  • 当最后一个中间件的 process_request 到达路由关系映射之后,返回到第一个中间件 process_view,然后依次往下,到达视图函数。

示例:

python

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request))

    def process_response(self, request, response):
        print("md1  process_response 方法!", id(request))
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("md1  process_view 方法!")   # 在视图之前执行,顺序执行
        # return view_func(request)

执行顺序:

text

请求 → MD1.process_request → MD2.process_request → 路由匹配
     → MD1.process_view → MD2.process_view → 视图函数
     → MD2.process_response → MD1.process_response → 响应
八、process_exception 方法

签名: process_exception(request, exception)

参数:

  • request:HttpRequest 对象

  • exception:视图函数异常产生的 Exception 对象

执行时机:

  • 只有在视图函数中出现异常了才执行

  • 按照 settings 的注册倒序执行。

  • 在视图函数之后,process_response 方法之前执行。

返回值:

  • None:页面会报 500 状态码错误,视图函数不会执行。倒序执行 process_exception,然后再倒序执行 process_response

  • HttpResponse 对象:页面不会报错,返回状态码为 200。视图函数不执行,该中间件后续的 process_exception 方法也不执行,直接从最后一个中间件的 process_response 方法倒序开始执行。

特殊情况: 若是 process_view 方法返回视图函数,提前执行了视图函数,且视图函数报错,则无论 process_exception 方法的返回值是什么,页面都会报错,且视图函数和 process_exception 方法都不执行,直接从最后一个中间件的 process_response 方法开始倒序执行。

示例:

python

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request))

    def process_response(self, request, response):
        print("md1  process_response 方法!", id(request))
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("md1  process_view 方法!")
        # return view_func(request)

    def process_exception(self, request, exception):
        print("md1  process_exception 方法!")
        # return HttpResponse(exception)   # 返回错误信息
九、四大方法执行顺序总结

正常流程(无异常):

text

请求
  ↓
MD1.process_request
MD2.process_request
  ↓
路由匹配
  ↓
MD1.process_view
MD2.process_view
  ↓
视图函数
  ↓
MD2.process_response
MD1.process_response
  ↓
响应

异常流程(视图函数抛出异常):

text

请求
  ↓
MD1.process_request
MD2.process_request
  ↓
MD1.process_view
MD2.process_view
  ↓
视图函数(抛出异常)
  ↓
MD2.process_exception
MD1.process_exception
  ↓
MD2.process_response
MD1.process_response
  ↓
响应

完整流程图:

十、方法执行规律总结
方法执行时机执行顺序返回值影响
process_request视图之前顺序返回 HttpResponse 则短路
process_viewprocess_request 之后,视图之前顺序返回 HttpResponse 则短路,返回 view_func 则提前执行视图
process_exception视图抛异常时倒序返回 HttpResponse 则吞掉异常
process_response视图之后倒序必须返回 response

记忆口诀:

  • 请求进来,顺序执行process_request → process_view

  • 响应出去,倒序执行process_exception → process_response

  • 越靠前的中间件,请求越先经过,响应越后离开

十一、实战示例:请求日志中间件

python

import time
from django.utils.deprecation import MiddlewareMixin

class LogMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.start_time = time.time()
        print(f"[请求] {request.method} {request.path}")

    def process_response(self, request, response):
        if hasattr(request, 'start_time'):
            duration = time.time() - request.start_time
            print(f"[响应] {request.path} 耗时 {duration:.3f}s 状态码 {response.status_code}")
        return response

注册:

python

MIDDLEWARE = [
    # ...
    'app01.middlewares.LogMiddleware',
]
十二、常见问题排查
问题现象可能原因解决方案
中间件不生效未在 MIDDLEWARE 中注册检查注册路径是否正确
process_response 报错忘记 return response必须返回 response 对象
请求被提前拦截某中间件 process_request 返回了 HttpResponse检查各中间件的返回值
执行顺序混乱注册顺序错误按业务需求调整 MIDDLEWARE 顺序
异常未被捕获process_exception 未定义或返回 None定义方法并返回 HttpResponse
修改 request 后视图取不到中间件执行顺序问题request 是同一对象,注意执行先后
十三、小结

本篇系统讲解了 Django 中间件的核心内容:

  • 作用:在请求与响应之间插入处理逻辑,可修改 request 和 response。

  • 配置:在 settings.py 的 MIDDLEWARE 中注册,顺序决定执行顺序。

  • 四大方法

    • process_request:视图之前,顺序执行。

    • process_view:路由匹配后、视图之前,顺序执行。

    • process_exception:视图抛异常时,倒序执行。

    • process_response:视图之后,倒序执行。

  • 返回值影响:返回 HttpResponse 会短路后续流程。

掌握中间件后,你已经能够为 Django 项目添加全局性的处理逻辑。下一篇我们将学习 Django 的缓存机制,提升高并发场景下的响应速度。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/Smell_of_earth/article/details/165831029

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--