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
md.py

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
process_request和process_view返回None

执行顺序:

  1. m1.request
  2. m2.request
  3. m1.view
  4. m2.view
  5. m2.response
  6. 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的process_request返回HttpResponse

执行顺序:

  1. m1.request
  2. 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的process_view返回HttpResponse

执行顺序:

  1. m1.request
  2. m2.request
  3. m1.view
  4. m2.response
  5. m1.response

 

 3. 在版本1.10之前

若process_request返回HttpResponse 对象,则当前中间件之后的process_request都不会执行,而从最后一个中间件的process_response向前返回

 

 

 

参考资料:

1. Python之路【第十六篇】:Django【基础篇】

2. http://code.ziqiangxuetang.com/django/django-middleware.html

 

以上是关于Django—middleware的主要内容,如果未能解决你的问题,请参考以下文章

django_heroku.settings(locals()) KeyError: 'MIDDLEWARE' 和 'MIDDLEWARE_CLASSES'

Django中Middleware中间件

利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击

django之(中间件)middleware

Django 中间件 Middleware

Django 中间件