本文目录导读:

是的,Django中间件的执行顺序是完全可配置的。
你只需要在项目的 settings.py 文件中的 MIDDLEWARE 列表里,调整各个中间件类的顺序即可,Django会严格按照这个列表的顺序来执行中间件。
执行顺序规则
理解Django中间件的执行顺序,需要掌握“洋葱模型”的概念:
对于列表中的中间件 [A, B, C]:
- 请求阶段:顺序是从上到下执行(A → B → C)。
- 响应阶段:顺序是从下到上执行(C → B → A)。
请求进入 → [A.process_request] → [B.process_request] → [C.process_request] → 视图函数
↓
响应返回 ← [A.process_response] ← [B.process_response] ← [C.process_response] ←
如何在settings.py中配置
# settings.py
MIDDLEWARE = [
# 安全相关(通常放在最前面)
'django.middleware.security.SecurityMiddleware',
# 会话和认证(需要在处理响应前设置cookie)
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# 自定义中间件(可以放在任何位置)
'myapp.middleware.MyCustomMiddleware',
# 点击劫持保护(通常放在最后)
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
自定义中间件的顺序考虑
如果你创建了自定义中间件,需要根据其功能选择合适的放置位置:
class MyCustomMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 请求阶段:在这里处理请求
# 放在前面可以早点处理请求,放在后面可以获取更多已经设置好的属性
response = self.get_response(request)
# 响应阶段:在这里处理响应
# 放在前面可以让响应先被处理,放在后面可以修改经过其他中间件处理的响应
return response
一些顺序建议
| 中间件类型 | 推荐位置 | 原因 |
|---|---|---|
| 安全相关 | 最前面 | 尽早拦截恶意请求 |
| 会话管理 | 靠前 | 后续中间件可能需要使用session |
| 认证授权 | 会话之后 | 需要先有session才能验证用户 |
| 性能统计 | 最外层 | 统计完整的请求处理时间 |
| 错误处理 | 最外层 | 捕获所有中间件和视图的异常 |
注意事项
-
依赖关系:某些中间件依赖于其他中间件的功能,
AuthenticationMiddleware依赖于SessionMiddleware,因此顺序不能颠倒。 -
性能影响:中间件的顺序会影响性能,将常用的、轻量的中间件放在前面,可以尽早过滤掉无效请求。
-
短路机制:如果某个中间件的
process_request返回了HttpResponse,则后续中间件和视图都不会执行,直接返回该响应,利用这个特性,可以将权限检查等中间件放在前面。 -
Django 1.10+ 的变化:从Django 1.10开始,
MIDDLEWARE_CLASSES改为MIDDLEWARE,并且推荐使用新的基于类的中间件编写方式。
你可以通过自由调整 MIDDLEWARE 列表中各个中间件的顺序,来控制它们在请求/响应处理链条中的位置。