首页 > 代码库 > Django—middleware

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