Django之Middleware(中间件)

中间件

  django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据本身的规则在合适的时机执行中间件中相应的方法。python

  在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每个元素就是一个中间件(内置) django

  详细:https://docs.djangoproject.com/en/2.2/ref/middleware/#security-middleware json

 

1 MIDDLEWARE = [
2     'django.middleware.security.SecurityMiddleware',
3     'django.contrib.sessions.middleware.SessionMiddleware',
4     'django.middleware.common.CommonMiddleware',
5     'django.middleware.csrf.CsrfViewMiddleware',
6     'django.contrib.auth.middleware.AuthenticationMiddleware',
7     'django.contrib.messages.middleware.MessageMiddleware',
8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
9 ]

  中间件中能够定义五个方法,分别是:缓存

  • process_request(self,request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

  以上方法的返回值能够是None和HttpResonse对象,若是是None,则继续按照django定义的规则向下执行,若是是HttpResonse对象,则直接将该对象返回给用户。session

Django的请求生命周期如图:函数

 自定义中间件

建立中间件类测试

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from django.shortcuts import HttpResponse
 5 from django.utils.deprecation import MiddlewareMixin
 6 
 7 
 8 class M1(MiddlewareMixin):
 9 
10     def process_request(self, request):
11         """
12         内部已经帮咱们返回
13         若是咱们本身加上返回值,在1.1版本前直接在当前中间件的process_response方法返回
14         在1.7 1.8版本后要跳到最后一个中间件的process_response方法一层层的返回
15         :param request:
16         :return:
17         """
18         print('m1.process_request')
19 
20     def process_view(self, request, callback, callback_args, callback_kwargs):
21         """
22         获得当前请求的执行视图函数名字
23         :param request:
24         :param callback:
25         :param callback_args:
26         :param callback_kwargs:
27         :return:
28         """
29         print('m1.process_view')
30         print(callback)
31         # 若是这里执行callback(就是视图函数的名字)函数,下面每个中间件的process_view方法都不走了,直接返回执行视图函数的结果
32         # 若是这里不执行callback视图函数方法,那么继续走下面中间件的process_view,若是都没执行(这里又有加装饰器的做用了,\
33         # 若是视图函数要加装饰器,那么这里加上装饰器)再走路由匹配,这样为视图函数巧妙的加上装饰器了
34 
35         # response = callback(request, *callback_args, **callback_kwargs)
36         # return response
37 
38     def process_response(self, request, response):
39         """
40         在这个环节已经经过了路由系统执行当前请求的视图函数了,一层层的返回字符串给用户
41         :param request:
42         :param response:
43         :return:
44         """
45         print('m1.process_response')
46         return response
47 
48     def process_exception(self, request, exception):
49         print('m1.process_exception')
50 
51     def process_template_response(self, request, response):
52         """
53         视图函数的返回值若是有render方法,才触发这个函数执行
54         :param request:
55         :param response:
56         :return:
57         """
58         print('m1.process_template_response')
59         return response
60 
61 
62 class M2(MiddlewareMixin):
63 
64     def process_request(self, request):
65         print('m2.process_request')
66 
67     def process_view(self, request, callback, callback_args, callback_kwargs):
68         print('m2.process_view')
69 
70     def process_response(self, request, response):
71         print('m2.process_response')
72         return response
73 
74     def process_exception(self, request, exception):
75         print('m2.process_exception')

注册中间件url

 1 MIDDLEWARE = [
 2     'django.middleware.security.SecurityMiddleware',
 3     'django.contrib.sessions.middleware.SessionMiddleware',
 4     'django.middleware.common.CommonMiddleware',
 5     'django.middleware.csrf.CsrfViewMiddleware',
 6     'django.contrib.auth.middleware.AuthenticationMiddleware',
 7     'django.contrib.messages.middleware.MessageMiddleware',
 8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 9     'md.M1',
10     'md.M2',
11 ]

 1.路由spa

urlpatterns = [
    path('index/', views.index),
]

2.视图3d

 1 from django.shortcuts import render, HttpResponse
 2 
 3 
 4 class Foo:
 5     def __init__(self, request, status, message):
 6         self.request = request
 7         self.status = status
 8         self.message = message
 9 
10     def render(self):
11         import json
12         result = {
13             'status': self.status,
14             'message': self.message
15         }
16         return HttpResponse(json.dumps(result))
17 
18 
19 def index(request):
20     # print('index执行视图函数')
21     # return HttpResponse('.........')
22     return Foo(request, True, "错误信息")

 

我把几个函数都写在一块儿分步骤测试的  测试以下图:(正常状况如上图请求生命周期,process_exception和process_template_response以下)  

上图测试的process_exception

总结下process_exception方法触发的机制流程图:

下图是测试process_template_response:

 

总结下process_template_response:视图函数的返回值若是有render方法,才触发这个函数执行

 

 

 

 

总结:

     中间件是有序的,从上到小依次执行,本质是由于一个列表

    应用:若是要对请求批量操做的时候就用中间件作

    0.对用户请求缓存中有,我就直接给你,没有就执行视图后续操做(从内存拿数据比从磁盘快多了嘛)

    1.作黑名单

    2.对全部请求日志的记录

    3.作认证权限

    4.装饰器局部使用,全局使用啊

    5.本身也能够作csrf_token认证

      等等不少的看需求

相关文章
相关标签/搜索