Django中settings.py的MIDDLEWARE里自定义中间件路径应设在哪里?
Django中间件在MIDDLEWARE列表中的配置位置问题
我参考Django文档在middleware/sample.py中创建了simple_middleware()中间件,但不清楚该中间件的路径"middleware.sample.simple_middleware"应该放在settings.py的MIDDLEWARE列表的开头、末尾还是任意位置。虽然知道文档里说中间件顺序很重要,但想明确具体该放哪里。
项目结构
django-project |-core | └-settings.py |-middleware | |-__init__.py | └-sample.py
middleware/sample.py 代码
def simple_middleware(get_response): print("Only once the server starts") def middleware(request): print("Before a view is called") response = get_response(request) print("After a view is called") return response return middleware
settings.py 中的MIDDLEWARE列表
MIDDLEWARE = [ # "middleware.sample.simple_middleware" # 开头? "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", # "middleware.sample.simple_middleware" # 任意位置? "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", # "middleware.sample.simple_middleware" # 末尾? ]
解答
首先要明确Django中间件的执行逻辑:
- 请求阶段(到达视图前):按照
MIDDLEWARE列表从上到下的顺序,执行每个中间件里get_response(request)之前的代码。 - 响应阶段(视图返回后):按照
MIDDLEWARE列表从下到上的顺序,执行每个中间件里get_response(request)之后的代码。
你的中间件仅做请求前后的日志打印,没有依赖其他中间件的功能(比如不需要读取session、用户认证信息),所以理论上可以放在任意位置,但不同位置会影响日志的打印顺序:
1. 放在列表开头
- 请求时:你的
Before a view is called会比所有Django内置中间件的前置代码先打印。 - 响应时:你的
After a view is called会比所有Django内置中间件的后置代码后打印。
2. 放在列表末尾
- 请求时:你的
Before a view is called会在所有Django内置中间件的前置代码执行完成后打印。 - 响应时:你的
After a view is called会在所有Django内置中间件的后置代码执行前打印。
3. 放在中间任意位置
- 请求时:先执行你上方所有中间件的前置代码,再打印你的
Before a view is called,最后执行你下方中间件的前置代码。 - 响应时:先执行你下方所有中间件的后置代码,再打印你的
After a view is called,最后执行你上方中间件的后置代码。
如果只是做日志记录这类无依赖的操作,推荐放在开头或者末尾:
- 放在开头可以完整覆盖整个请求响应周期,最先捕获请求、最后处理响应;
- 放在末尾则是最后处理请求、最先处理响应。
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

