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

原文地址:https://www.cnblogs.com/OldJack/p/7112811.html