Django中间件Middleware工作原理与自定义实现详解
本文深入解析Django框架中Middleware(中间件)的工作机制与执行流程。详细说明了从请求到响应的五个核心Hook方法:process_request、process_view、process_template_response、process_exception及process_response的执行顺序与条件。通过具体代码示例,演示如何在settings中激活中间件并编写自定义中间类,帮助开发者掌握全局请求处理与错误拦截的最佳实践。
一、中间件
Middleware(中间件)是Django请求/响应处理流程中的插件框架。它作为一个轻量级的底层“插件”系统,允许开发者全局性地修改Django的输入或输出行为。
每个中间件组件负责执行特定的功能。例如,Django内置的AuthenticationMiddleware中间件负责将用户身份与使用会话的请求进行关联。
本文档将介绍中间件的工作原理、激活方法以及如何编写自定义中间件。Django提供了一系列可直接使用的内置中间件,具体细节可参考内置中间件参考文档。
二、激活中间件
要激活中间件,需将其类路径添加到Django设置文件中的MIDDLEWARE列表里。以下配置示例展示了如何激活三个自定义中间件:Middleware.test.m1、Middleware.test.m2和Middleware.test.m3。
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',
'Middleware.test.m1',
'Middleware.test.m2',
'Middleware.test.m3',
]
三、中间件请求和响应
在请求阶段,调用视图函数(views)之前,Django会按照MIDDLEWARE列表中定义的顺序,从上到下依次调用各个中间件。
Django中间件的执行过程主要分为两个阶段:从上到下的Hooks和从下到上的Hooks。
从上到下的Hooks包括:
- process_request()
- process_view()
从下到上的Hooks包括:
- process_exception()
- process_template_response()
- process_response()
四、中间件处理流程说明
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',
'Middleware.test.m1',
'Middleware.test.m2',
'Middleware.test.m3',
]
一个完整的中间件至少需要包含一个process_request Hook和一个process_response Hook。前者用于处理传入的请求,后者用于处理返回的响应。
除了上述两个必需的Hook外,中间件还可以实现其他三个可选的Hook,分别是process_view、process_exception和process_template_response。
process_view主要用于执行中间件中针对视图函数的具体处理逻辑。如前所述,它属于从上到下的Hooks,意味着process_view会在视图函数(views)执行之前运行。
process_exception通常不会执行,只有当视图函数中出现异常(exception)时才会触发。根据中间件请求阶段的描述,它属于从下到上的Hooks,即在视图函数执行之后(出错后)才会执行。
process_template_response同样属于非默认执行的Hook。只有当视图函数返回的对象中包含render方法时,该方法才会被调用。
五、中间件处理顺序
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',
'Middleware.test.m1',
'Middleware.test.m2',
'Middleware.test.m3',
]
1、process_request阶段:当用户发起请求后,请求会经过所有已注册的中间件,并自上而下执行。系统会先执行所有中间件的process_request方法。如果某个process_request返回HttpResponse对象,则流程中断,立即从当前中间件开始向上执行process_response;如果返回None,则继续向下执行下一个中间件的process_request。
2、process_view阶段:当所有中间件的process_request方法执行完毕且均返回None后,系统开始执行所有中间件的process_view方法。如果其中一个process_view返回HttpResponse,则跳过后续所有中间件的process_view执行,直接转为从最底层中间件开始自下而上执行process_response;若返回None,则继续向下执行。
3、views阶段:当所有中间件的process_request和process_view阶段执行完毕,且均未返回HttpResponse(即都返回None)时,请求将进入视图函数(views)执行。
在views阶段,可能出现三种情况:(1) 视图函数返回的对象中包含render方法;(2) 视图函数执行过程中产生异常;(3) 视图函数返回对象中包含render方法,且执行过程中产生异常。
针对上述情况:若出现第一种情况,系统开始执行所有中间件的process_template_response方法,并自下而上在每个定义了该方法的中间件中依次执行;若出现第二种情况,系统开始执行所有中间件的process_exception方法,并自下而上在每个定义了该方法的中间件中依次执行;若出现第三种情况,系统会自下而上同时执行所有中间件中定义的process_exception和process_template_response方法。在此情况下,优先执行所有中间件中的process_template_response,随后再执行所有中间件中的process_exception。
4、process_response阶段:当process_request、process_view、views、process_template_response及process_exception方法全部执行完成后,系统开始自下而上从中间件中执行process_response方法,直到最上层中间件的process_response执行完毕,最终将响应返回给用户。
六、Django 自定义中间件
1、在settings中定义三个中间件
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',
'Middleware.test.m1',
'Middleware.test.m2',
'Middleware.test.m3',
]
2、创建中间件路径
在项目根路径下创建中间件目录及文件,例如:./Middleware/test.py。
3、定义中间件
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse
class m1(MiddlewareMixin):
def process_request(self, request):
print('m1 request')
def process_view(self, request, func_view, func_args, func_kwargs):
print('m1 view')
def process_response(self, request, response):
print('m1 response')
return response
def process_exception(self, request, exception):
print('m1 exception')
def process_template_response(self, request, response):
print('m1 template response')
return response
class m2(MiddlewareMixin):
def process_request(self, request):
print('m2 request')
def process_view(self, request, func_view, func_args, func_kwargs):
print('m2 view')
def process_response(self, request, response):
print('m2 response')
return response
def process_exception(self, request, exception):
print('m2 exception')
def process_template_response(self, request, response):
print('m2 template response')
return response
class m3(MiddlewareMixin):
def process_request(self, request):
print('m3 request')
def process_view(self, request, func_view, func_args, func_kwargs):
print('m3 view')
def process_response(self, request, response):
print('m3 response')
return response
def process_exception(self, request, exception):
print('m3 exception')
def process_template_response(self, request, response):
print('m3 template response')
return response
4、定义视图函数
class Foo:
def render(self):
int('v')
return HttpResponse('OK')
def middleware(request):
#return render(request, 'login.html')
#return HttpResponse('middleware')
return Foo()
七、一个请求经过中间件的请求周期
为了清晰展示执行顺序,示例中的视图函数故意包含一个报错以触发中间件中定义的process_exception方法。具体报错内容已被移除以便聚焦于中间件流程。
m1 request
m2 request
m3 request
m1 view
m2 view
m3 view
m3 template response
m2 template response
m1 template response
m3 exception
m2 exception
m1 exception
m3 response
m2 response
m1 response
八、结论
开发者可根据实际需求编写中间件,并通过测试验证每个方法的执行顺序。中间件主要包含5个方法,分别为:process_request、process_view、process_template_response、process_exception和process_response。
另外需要注意:Django官方不建议在中间件层处理request.POST数据,CSRF中间件是一个例外,因为它需要全局安全地处理用户Token。
到此这篇关于Django框架之中间件Middleware的实现的文章就介绍到这了,更多相关Django 中间件Middleware内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









