中间件不执行的根本原因是注册未生效或执行顺序异常:路径错误、模块缺失、debug条件屏蔽、process_request提前返回、顺序错位、wsgi配置丢失,均导致django静默跳过。

中间件不执行,八成是注册没生效或顺序卡死了——不是代码写错,而是 Django 根本没调用它。
中间件类路径写错或没进 MIDDLEWARE 列表
这是最隐蔽也最常被忽略的问题:Django 对路径大小写、点号、模块层级极其敏感,写错一个字符就静默跳过。
-
MIDDLEWARE里必须填完整路径,比如"myapp.middleware.IPBlockMiddleware",不能漏掉middleware.或写成"myapp.IPBlockMiddleware" - 路径中任意一级模块不存在(比如
myapp目录下没__init__.py),Django 不报错,但该中间件永远不加载 - 开发时用了
if DEBUG:包裹中间件注册?生产环境DEBUG=False下它直接消失 - 检查方法:在
manage.py shell里运行from django.conf import settings; print(settings.MIDDLEWARE),确认列表里真有你的路径,且无空格、换行、中文逗号
process_request 返回了值,但后续中间件和视图全被跳过
很多人以为“执行了中间件”=“看到日志”,其实 process_request 一旦返回非 None 值(比如 HttpResponse),整个请求链立刻终止——后面所有中间件、process_view、视图函数全不执行。
- 典型误用:在 IP 黑名单中间件里写了
return HttpResponseForbidden(),却没意识到这会导致AuthenticationMiddleware和SessionMiddleware都没机会运行 - 想记录日志+放行?必须显式
return None(或直接不写 return) - 想拦截又不想破坏 session 初始化?把中间件位置调到
SessionMiddleware和AuthenticationMiddleware之后——但这时request.user已可用,判断逻辑更稳
中间件顺序导致根本没走到你的类
Django 按 MIDDLEWARE 列表从上到下执行 process_request,从下到上执行 process_response。顺序不对,等于没写。
-
SecurityMiddleware如果在你前面,且触发了DisallowedHost异常,请求连process_request都不会进你的中间件 -
CorsMiddleware如果放在CommonMiddleware后面,响应头加不上,浏览器收不到Access-Control-Allow-Origin -
WhiteNoiseMiddleware如果在SecurityMiddleware前面,静态文件请求可能被 CSP 策略直接拒绝 - 验证方法:在每个中间件的
process_request开头加print(f"[{self.__class__.__name__}] entered"),看控制台输出顺序是否符合预期
WSGI 入口没传入中间件配置
本地 runserver 正常,上线后完全不触发?大概率是 WSGI 脚本没加载 settings 或中间件配置丢失。
- Django 5.0+ 的
wsgi.py必须确保os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')这行存在且路径正确 - 用 Gunicorn 启动时,如果命令里指定了
--env DJANGO_SETTINGS_MODULE=...,但实际项目结构变了,settings 模块路径就失效 - Nginx + uWSGI 场景下,
uwsgi.ini中的env = DJANGO_SETTINGS_MODULE=...必须与项目真实路径一致 - 最简验证:在
wsgi.py最底部加一行print("WSGI loaded, MIDDLEWARE count:", len(settings.MIDDLEWARE)),看启动日志有没有输出
真正难排查的不是“怎么写”,而是“为什么没走”——它不报错、不抛异常,只安静地跳过。每次怀疑中间件失效,先打印 settings.MIDDLEWARE 和各中间件的进入日志,比反复改逻辑快得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











