Django—middleware
一、Django中间件的请求周期
我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下:

也就是说,每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。
二、自定义及注册中间件
1. 创建中间件
在project根目录下创建中间件py文件:
class RequestExeute(object): def process_request(self, request): print('process_request') def process_view(self, request, callback, callback_args, callback_kwargs): print('process_view') def process_exception(self, request, exception): """ 当views函数出错时执行 :param request: :param exception: :return: """ print('process_exception') def process_response(self, request, response): """ 必须return HttpResponse :param request: :param response: :return: """ print('process_response') return response def process_template_response(self, request, response): """ 视图函数的返回值中,如果有render方法,才被调用 :param request: :param response: :return: """ print('process_template_response') return response
2. 注册中间件
在settings.py文件中,按照欲执行的顺序注册:

ps. 在1.9及之前的版本中,中间件的关键字为:MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = (
'zqxt.middleware.BlockedIpMiddleware',
...其它的中间件
)
三、中间件中方法的执行顺序
1. 正常状况
from django.shortcuts import HttpResponse from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self, request): print('m1.request') # return HttpResponse('request_m1') def process_view(self, request, callback, callback_args, callback_kwargs): print('m1.view') # response = callback(request, *callback_args, **callback_kwargs) # return response def process_response(self, request, response): print('m1.response') return response def process_exception(self, request, exception): print('m1.process_exception') return HttpResponse('m1.process_exception') def process_template_response(self, request, response): """ 视图函数的返回值中,如果有render方法,才被调用 :param request: :param response: :return: """ print('m1.process_template_response') return response class M2(MiddlewareMixin): def process_request(self, request): print('m2.request') def process_view(self, request, callback, callback_args, callback_kwargs): print('m2.view') # response = callback(request, *callback_args, **callback_kwargs) # return response def process_response(self, request, response): print('m2.response') return response def process_exception(self, request, exception): print('m2.process_exception') return HttpResponse('m2.process_exception') def process_template_response(self, request, response): """ 视图函数的返回值中,如果有render方法,才被调用 :param request: :param response: :return: """ print('m2.process_template_response') return response
执行顺序:
- m1.request
- m2.request
- m1.view
- m2.view
- m2.response
- m1.response
2. 在版本1.10及之后
若process_request返回HttpResponse 对象,则从当前中间件的process_response向前返回
from django.shortcuts import HttpResponse from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self, request): print('m1.request') return HttpResponse('request_m1') def process_view(self, request, callback, callback_args, callback_kwargs): print('m1.view') # response = callback(request, *callback_args, **callback_kwargs) # return response def process_response(self, request, response): print('m1.response') return response def process_exception(self, request, exception): print('m1.process_exception') return HttpResponse('m1.process_exception') def process_template_response(self, request, response): """ 视图函数的返回值中,如果有render方法,才被调用 :param request: :param response: :return: """ print('m1.process_template_response') return response class M2(MiddlewareMixin): def process_request(self, request): print('m2.request') def process_view(self, request, callback, callback_args, callback_kwargs): print('m2.view') # response = callback(request, *callback_args, **callback_kwargs) # return response def process_response(self, request, response): print('m2.response') return response def process_exception(self, request, exception): print('m2.process_exception') return HttpResponse('m2.process_exception') def process_template_response(self, request, response): """ 视图函数的返回值中,如果有render方法,才被调用 :param request: :param response: :return: """ print('m2.process_template_response') return response # class RequestExeute(object): # def process_request(self, request): # print('process_request') # # def process_view(self, request, callback, callback_args, callback_kwargs): # print('process_view') # # def process_exception(self, request, exception): # """ # 当views函数出错时执行 # :param request: # :param exception: # :return: # """ # print('process_exception') # # def process_response(self, request, response): # """ # 必须return HttpResponse # :param request: # :param response: # :return: # """ # print('process_response') # return response # # def process_template_response(self, request, response): # """ # 视图函数的返回值中,如果有render方法,才被调用 # :param request: # :param response: # :return: # """ # print('process_template_response') # return response
执行顺序:
- m1.request
- m1.response
process_view与process_request类似:
from django.shortcuts import HttpResponse from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self, request): print('m1.request') # return HttpResponse('request_m1') def process_view(self, request, callback, callback_args, callback_kwargs): print('m1.view') response = callback(request, *callback_args, **callback_kwargs) return response def process_response(self, request, response): print('m1.response') return response def process_exception(self, request, exception): print('m1.process_exception') return HttpResponse('m1.process_exception') def process_template_response(self, request, response): """ 视图函数的返回值中,如果有render方法,才被调用 :param request: :param response: :return: """ print('m1.process_template_response') return response class M2(MiddlewareMixin): def process_request(self, request): print('m2.request') def process_view(self, request, callback, callback_args, callback_kwargs): print('m2.view') # response = callback(request, *callback_args, **callback_kwargs) # return response def process_response(self, request, response): print('m2.response') return response def process_exception(self, request, exception): print('m2.process_exception') return HttpResponse('m2.process_exception') def process_template_response(self, request, response): """ 视图函数的返回值中,如果有render方法,才被调用 :param request: :param response: :return: """ print('m2.process_template_response') return response
执行顺序:
- m1.request
- m2.request
- m1.view
- m2.response
- m1.response
3. 在版本1.10之前
若process_request返回HttpResponse 对象,则当前中间件之后的process_request都不会执行,而从最后一个中间件的process_response向前返回
参考资料:
2. http://code.ziqiangxuetang.com/django/django-middleware.html

浙公网安备 33010602011771号