在學習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中介軟體的介紹,希望和大家多多學習!轉載請說明出處,尊重勞動成果!!!