Django—middleware
Posted 三百六十行,行行转IT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django—middleware相关的知识,希望对你有一定的参考价值。
一、Django中间件的请求周期
我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下:
也就是说,每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。
二、自定义及注册中间件
1. 创建中间件
在project根目录下创建中间件py文件:
1 class RequestExeute(object): 2 def process_request(self, request): 3 print(\'process_request\') 4 5 def process_view(self, request, callback, callback_args, callback_kwargs): 6 print(\'process_view\') 7 8 def process_exception(self, request, exception): 9 """ 10 当views函数出错时执行 11 :param request: 12 :param exception: 13 :return: 14 """ 15 print(\'process_exception\') 16 17 def process_response(self, request, response): 18 """ 19 必须return HttpResponse 20 :param request: 21 :param response: 22 :return: 23 """ 24 print(\'process_response\') 25 return response 26 27 def process_template_response(self, request, response): 28 """ 29 视图函数的返回值中,如果有render方法,才被调用 30 :param request: 31 :param response: 32 :return: 33 """ 34 print(\'process_template_response\') 35 return response
2. 注册中间件
在settings.py文件中,按照欲执行的顺序注册:
ps. 在1.9及之前的版本中,中间件的关键字为:MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = ( \'zqxt.middleware.BlockedIpMiddleware\', ...其它的中间件 )
三、中间件中方法的执行顺序
1. 正常状况
1 from django.shortcuts import HttpResponse 2 from django.utils.deprecation import MiddlewareMixin 3 class M1(MiddlewareMixin): 4 def process_request(self, request): 5 print(\'m1.request\') 6 # return HttpResponse(\'request_m1\') 7 8 def process_view(self, request, callback, callback_args, callback_kwargs): 9 print(\'m1.view\') 10 # response = callback(request, *callback_args, **callback_kwargs) 11 # return response 12 13 def process_response(self, request, response): 14 print(\'m1.response\') 15 return response 16 17 def process_exception(self, request, exception): 18 print(\'m1.process_exception\') 19 return HttpResponse(\'m1.process_exception\') 20 21 def process_template_response(self, request, response): 22 """ 23 视图函数的返回值中,如果有render方法,才被调用 24 :param request: 25 :param response: 26 :return: 27 """ 28 print(\'m1.process_template_response\') 29 return response 30 31 32 class M2(MiddlewareMixin): 33 def process_request(self, request): 34 print(\'m2.request\') 35 36 def process_view(self, request, callback, callback_args, callback_kwargs): 37 print(\'m2.view\') 38 # response = callback(request, *callback_args, **callback_kwargs) 39 # return response 40 41 def process_response(self, request, response): 42 print(\'m2.response\') 43 return response 44 45 def process_exception(self, request, exception): 46 print(\'m2.process_exception\') 47 return HttpResponse(\'m2.process_exception\') 48 49 def process_template_response(self, request, response): 50 """ 51 视图函数的返回值中,如果有render方法,才被调用 52 :param request: 53 :param response: 54 :return: 55 """ 56 print(\'m2.process_template_response\') 57 return response
执行顺序:
- m1.request
- m2.request
- m1.view
- m2.view
- m2.response
- m1.response
2. 在版本1.10及之后
若process_request返回HttpResponse 对象,则从当前中间件的process_response向前返回
1 from django.shortcuts import HttpResponse 2 from django.utils.deprecation import MiddlewareMixin 3 class M1(MiddlewareMixin): 4 def process_request(self, request): 5 print(\'m1.request\') 6 return HttpResponse(\'request_m1\') 7 8 def process_view(self, request, callback, callback_args, callback_kwargs): 9 print(\'m1.view\') 10 # response = callback(request, *callback_args, **callback_kwargs) 11 # return response 12 13 def process_response(self, request, response): 14 print(\'m1.response\') 15 return response 16 17 def process_exception(self, request, exception): 18 print(\'m1.process_exception\') 19 return HttpResponse(\'m1.process_exception\') 20 21 def process_template_response(self, request, response): 22 """ 23 视图函数的返回值中,如果有render方法,才被调用 24 :param request: 25 :param response: 26 :return: 27 """ 28 print(\'m1.process_template_response\') 29 return response 30 31 32 class M2(MiddlewareMixin): 33 def process_request(self, request): 34 print(\'m2.request\') 35 36 def process_view(self, request, callback, callback_args, callback_kwargs): 37 print(\'m2.view\') 38 # response = callback(request, *callback_args, **callback_kwargs) 39 # return response 40 41 def process_response(self, request, response): 42 print(\'m2.response\') 43 return response 44 45 def process_exception(self, request, exception): 46 print(\'m2.process_exception\') 47 return HttpResponse(\'m2.process_exception\') 48 49 def process_template_response(self, request, response): 50 """ 51 视图函数的返回值中,如果有render方法,才被调用 52 :param request: 53 :param response: 54 :return: 55 """ 56 print(\'m2.process_template_response\') 57 return response 58 59 60 # class RequestExeute(object): 61 # def process_request(self, request): 62 # print(\'process_request\') 63 # 64 # def process_view(self, request, callback, callback_args, callback_kwargs): 65 # print(\'process_view\') 66 # 67 # def process_exception(self, request, exception): 68 # """ 69 # 当views函数出错时执行 70 # :param request: 71 # :param exception: 72 # :return: 73 # """ 74 # print(\'process_exception\') 75 # 76 # def process_response(self, request, response): 77 # """ 78 # 必须return HttpResponse 79 # :param request: 80 # :param response: 81 # :return: 82 # """ 83 # print(\'process_response\') 84 # return response 85 # 86 # def process_template_response(self, request, response): 87 # """ 88 # 视图函数的返回值中,如果有render方法,才被调用 89 # :param request: 90 # :param response: 91 # :return: 92 # """ 93 # print(\'process_template_response\') 94 # return response
执行顺序:
- m1.request
- m1.response
process_view与process_request类似:
1 from django.shortcuts import HttpResponse 2 from django.utils.deprecation import MiddlewareMixin 3 class M1(MiddlewareMixin): 4 def process_request(self, request): 5 print(\'m1.request\') 6 # return HttpResponse(\'request_m1\') 7 8 def process_view(self, request, callback, callback_args, callback_kwargs): 9 print(\'m1.view\') 10 response = callback(request, *callback_args, **callback_kwargs) 11 return response 12 13 def process_response(self, request, response): 14 print(\'m1.response\') 15 return response 16 17 def process_exception(self, request, exception): 18 print(\'m1.process_exception\') 19 return HttpResponse(\'m1.process_exception\') 20 21 def process_template_response(self, request, response): 22 """ 23 视图函数的返回值中,如果有render方法,才被调用 24 :param request: 25 :param response: 26 :return: 27 """ 28 print(\'m1.process_template_response\') 29 return response 30 31 32 class M2(MiddlewareMixin): 33 def process_request(self, request): 34 print(\'m2.request\') 35 36 def process_view(self, request, callback, callback_args, callback_kwargs): 37 print(\'m2.view\') 38 # response = callback(request, *callback_args, **callback_kwargs) 39 # return response 40 41 def process_response(self, request, response): 42 print(\'m2.response\') 43 return response 44 45 def process_exception(self, request, exception): 46 print(\'m2.process_exception\') 47 return HttpResponse(\'m2.process_exception\') 48 49 def process_template_response(self, request, response): 50 """ 51 视图函数的返回值中,如果有render方法,才被调用 52 :param request: 53 :param response: 54 :return: 55 """ 56 print(\'m2.process_template_response\') 57 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
以上是关于Django—middleware的主要内容,如果未能解决你的问题,请参考以下文章
django_heroku.settings(locals()) KeyError: 'MIDDLEWARE' 和 'MIDDLEWARE_CLASSES'
利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击