django中間件介紹
- 2021 年 2 月 19 日
- 筆記
- python之django框架
在學習django中間件之前,先來認識一下django的生命周期,如下圖所示:

django生命周期:瀏覽器發送的請求會先經過wsgiref模組處理解析出request(請求數據)給到中間件,然後通過路由控制執行對應的視圖函數,從而和模板,db進行交互,交互完的數據再通過視圖函數返回給中間件,最後wsgiref模組將返回的數據封裝成http形式的數據給到瀏覽器並進行展示。
了解了django的生命周期後,我們就可以開始著手寫一個自己的中間件了,接下來認識幾個常用的中間件方法
1.process_request
單個中間件
首先在app下創建一個py文件,定義你的中間件類名
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1')
然後將你的py文件路徑寫入django主項目的settings的MIDDLEWARE中
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'proxy_pro.middleware.MiddlewareShow' # 此條是新加的 從該項目路徑開始寫 ]
然後執行一個視圖函數即可,查看控制台列印

此時自己創建的process_request方法就生效了
多個中間件
此時在之前的py文件中再新建一個類
class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request')
然後將新建類的路徑也放在django主項目的settings的MIDDLEWARE中
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'proxy_pro.middleware.MiddlewareShow', 'proxy_pro.middleware.MiddlewareShowTwo' ]
執行視圖函數,查看控制台列印

此時定義的兩個中間件都生效了,執行順序是先1後2
2.process_response
分別在剛才的類中添加response方法
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') def process_response(self, request, response): print('MiddlewareShow1 Response') return response class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request') def process_response(self, request, response): print('MiddlewareShow2 Response') return response
執行視圖函數,查看控制台列印

此時可以看出請求先依次執行了中間件的Request,然後再去執行視圖函數,返回是先執行跟後面的中間件再依次往前
這時突然冒出一個想法,如果在request時直接返回了某個東西,還會繼續去執行後面的視圖函數嗎?那我們就來測試一下
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') return HttpResponse('request1時已返回') def process_response(self, request, response): print('MiddlewareShow1 Response') return response class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request') def process_response(self, request, response): print('MiddlewareShow2 Response') return response
執行視圖函數,查看控制台

此時可以看出當request中有返回時,直接不執行後面的內容了
3.process_view
分別在剛才的py文件中添加view方法
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') def process_response(self, request, response): print('MiddlewareShow1 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow1 process_view') class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request') def process_response(self, request, response): print('MiddlewareShow2 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow2 process_view')
執行視圖函數,查看控制台返回

此時可以看出這個process_view方法會在執行完request後執行,執行完再去執行視圖函數
這時候就有疑問了,那這個有什麼用呢?我們先把它裡面的參數列印一下
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') def process_response(self, request, response): print('MiddlewareShow1 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow1 process_view') print('=====>callback', callback) print('=====>callback_args', callback_args) class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request') def process_response(self, request, response): print('MiddlewareShow2 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow2 process_view')
執行視圖函數列印結果

此時可以看到這個view裡面的參數callback是視圖方法,callback_args是請求參數,那我們試著去請求下看看
class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') def process_response(self, request, response): print('MiddlewareShow1 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow1 process_view') print('=====>callback', callback) print('=====>callback_args', callback_args) ret = callback(callback_args) # 請求 return ret class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request') def process_response(self, request, response): print('MiddlewareShow2 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow2 process_view')
查看列印結果

結果顯然易見,請求視圖函數成功了,返回了以後就沒有去執行process_view2了,這邊的作用就是可以攔截請求
4.process_exception
分別在剛才的py文件中添加exception方法
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') def process_response(self, request, response): print('MiddlewareShow1 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow1 process_view') # print('=====>callback', callback) # print('=====>callback_args', callback_args) # ret = callback(callback_args) # return ret def process_exception(self, request, exception): print('MiddlewareShow1 process_exception') return HttpResponse(exception) class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request') def process_response(self, request, response): print('MiddlewareShow2 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow2 process_view') def process_exception(self, request, exception): print('MiddlewareShow2 process_exception') return HttpResponse(exception)
執行視圖函數,查看控制台

問題來了,為啥沒有走這個中間件方法呢?別慌,我們在視圖函數中加個錯
def middle_show(request): leo print('執行了視圖函數') return HttpResponse('hhh')
此時在執行下看看

此時可以看到當process_exception2獲取到報錯後,就返回了沒有執行process_exception1
那如果我們在process_exception1處理呢,我們來測試下
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class MiddlewareShow(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow1 Request') def process_response(self, request, response): print('MiddlewareShow1 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow1 process_view') # print('=====>callback', callback) # print('=====>callback_args', callback_args) # ret = callback(callback_args) # return ret def process_exception(self, request, exception): print('MiddlewareShow1 process_exception') return HttpResponse(exception) class MiddlewareShowTwo(MiddlewareMixin): def process_request(self, request): print('MiddlewareShow2 Request') def process_response(self, request, response): print('MiddlewareShow2 Response') return response def process_view(self, request, callback, callback_args, callback_kwargs): print('MiddlewareShow2 process_view') def process_exception(self, request, exception): print('MiddlewareShow2 process_exception')
執行視圖函數,列印看下

此時還會走到process_exception1哦,然後把錯誤返回給頁面。
以上就是django中間件的介紹,希望和大家多多學習!轉載請說明出處,尊重勞動成果!!!

