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認證

      等等不少的看需求

相關文章
相關標籤/搜索