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 ]
中間件中能夠定義五個方法,分別是:緩存
以上方法的返回值能夠是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認證
等等不少的看需求