为了验证中间件功能和函数执行过程,手动注册3个中间件到setting.py文件中
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',
'Middle.m1.Middle1',
'Middle.m1.Middle2',
'Middle.m1.Middle3',
]
3个中间件代码
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse class Middle1(MiddlewareMixin):
def process_request(self,request):
print('第一个中间件的请求函数') def process_view(self,request, callback_func, callback_func_args, callback_func_kwargs):
# url(r'^user_list\d+', views.user_list)
# callback_func_args --> 存没有变量名的参数
# url(r'^user_list(?P<nid>\d+)', views.user_list)
# callback_func_kwargs --> 存有变量名的参数
print('第一个中间件的视图函数') def process_exception(self, request, exception):
#如果views.py函数执行出错,自动执行
if isinstance(exception, ValueError):
print('第一个中间件的异常处理函数') def process_response(self,request,response):
print('第一个中间件的回复函数')
return response def process_template_response(self, request, response):
#默认不执行
#如果views返回的对象中具有render方法,该方法自动执行 print('第一个中间件的模板函数')
return response class Middle2(MiddlewareMixin):
def process_request(self,request):
print('第二个中间件的请求函数') def process_view(self,request, callback_func, callback_func_args, callback_func_kwargs):
print('第二个中间件的视图函数') def process_exception(self, request, exception):
if isinstance(exception, ValueError):
print('第二个中间件的异常处理函数')
# return HttpResponse("发生ValueError错误。。。") def process_response(self,request,response):
print('第二个中间件的回复函数')
return response def process_template_response(self, request, response):
print('第二个中间件的模板函数')
return response class Middle3(MiddlewareMixin):
def process_request(self,request):
print('第三个中间件的请求函数') def process_view(self,request, callback_func, callback_func_args, callback_func_kwargs):
print('第三个中间件的视图函数') def process_response(self,request,response):
print('第三个中间件的回复函数')
return response def process_exception(self, request, exception):
if isinstance(exception,ValueError):
print('第三个中间件的异常处理函数')
#return HttpResponse("发生ValueError错误。。。") def process_template_response(self, request, response):
print('第三个中间件的模板函数')
return response
#render方法的执行
class Foo():
def render(self):
return HttpResponse("<h1>readding a book!!</h1>")
def read(request):return Foo()
加入中间件后的请求周期
完整的请求周期:
request1 -> request2 -> request3 -> 路由映射匹配(获取view中的回调参数) ->
view1 -> view2 -> view3 -> views中的函数 -> response3 -> response2 -> response1 request函数return:
Django1.8、1.9之前:request1 -> request2(return) ->response3 -> response2 -> response1
Django1.10之后:request1 -> request2(return) -> response2 -> response1 views.py中的函数执行报错(exceptionX不return):
request1 -> request2 -> request3 -> 路由映射匹配(获取view中的回调参数) ->
view1 -> view2 -> view3 -> views中的函数异常 -> exception3 -> exception2 -> exception1 ->
response3 -> response2 -> response1 views.py中的函数执行报错(exception2--->return):
request1 -> request2 -> request3 -> 路由映射匹配(获取view中的回调参数) ->
view1 -> view2 -> view3 -> views中的函数异常 -> exception3 -> exception2 ->
response3 -> response2 -> response1 加上template函数之后的请求周期:
#template只有在views.py中执行了render方法后才会被调用,并且他自己也必须要返回response
request1 -> request2 -> request3 -> 路由映射匹配(获取view中的回调参数) ->
view1 -> view2 -> view3 -> views中的函数 ->
template3 -> template2 -> template1 ->
response3 -> response2 -> response1