Django框架之中間件MiddleWare的實現(xiàn)
一、中間件
Middleware是Django請求/響應處理的插件框架。它是一個輕巧的低級"插件"系統(tǒng),用于全局改變Django的輸入或輸出。
每個中間件組件負責執(zhí)行某些特定功能。例如,Django包含一個中間件組件 AuthenticationMiddleware,它將用戶與使用會話的請求相關聯(lián)。
該文檔介紹了中間件的工作原理,如何激活中間件以及如何編寫自己的中間件。Django附帶了一些你可以直接使用的內置中間件。它們記錄在內置中間件參考中
二、激活中間件
要激活中間件,請將其添加到MIDDLEWARE Django設置中的列表中
如下,我激活了三個中間件 Middleware.test.m1,Middleware.test.m2,Middleware.test.m3
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', 'Middleware.test.m1', 'Middleware.test.m2', 'Middleware.test.m3', ]
三、中間件請求和響應
在請求階段,調用views之前,django按照MIDDLEWARE_CLASSES中定義的順序從上到下調用中間件。
在Django中間件中,總共有分為從上到下hooks和從下到上hooks
從上到下hooks:
- process_request()
- process_view()
從下到上hooks:
- process_exception()
- process_template_response()
- process_response()
四、中間件處理流程說明(如下述的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', 'Middleware.test.m1', 'Middleware.test.m2', 'Middleware.test.m3', ]
一個中間件最少有一個process_request hooks和一個process_response hooks,前者是用來處理請求的,后者是用來處理響應的
那除了必須的兩個hooks以外,還有其他三個hooks,分別是 process_view, process_exception, process_template_response
process_view 主要是用來執(zhí)行middleware中具體的處理函數(shù),如中間件請求中所說,是從上到下的hooks,表示process_view在views視圖函數(shù)之前執(zhí)行
process_exception 一般情況下不會執(zhí)行,只有在views視圖函數(shù)中出現(xiàn)exception異常時,才會執(zhí)行;如中間件請求中所說,是從下到上的hooks,表示processs_exception在views視圖函數(shù)之后執(zhí)行,也就是views視圖函數(shù)出錯之后,才會執(zhí)行
processs_template_response 一般情況下也不會執(zhí)行,也就是說,只有views中的函數(shù)返回對象中具有render方法,它才會執(zhí)行
五、中間件處理順序(如下述的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', 'Middleware.test.m1', 'Middleware.test.m2', 'Middleware.test.m3', ]
1、process_request 階段
當一個用戶發(fā)起請求后,該請求會經過上述的所有中間件,并且自上而下執(zhí)行;先執(zhí)行所有中間件的 process_request方法,該方法如果返回HttpResponse,則執(zhí)行從當前的中間件向上執(zhí)行 process_responsse,如果返回None,則接著向下執(zhí)行 process_request
2、process_view 階段
當該用戶的請求執(zhí)行完所有中間件 process_request 方法后,如果返回都為None,那么接下來會執(zhí)行所有中間件的 process_view 方法,如果其中一個 process_view 返回HttpResponse,則會跳過接下來所有中間件的 process_view,直接會從最下面的process_response自下而上執(zhí)行,如果process_view返回None,則會繼續(xù)向下執(zhí)行
3、views 階段
當該用戶的請求執(zhí)行完所有的process_request和process_view階段,并且沒有返回HttpResponse;換句話說,返回的都是None,那么這個時候就會到達views視圖函數(shù)
在這里,可能會有三種可能性
(1) views中的函數(shù)返回對象中具有render方法
(2) views中的函數(shù)產生異常
(3) views中的函數(shù)返回對象中具有render方法,并且views中的函數(shù)產生異常
當出現(xiàn)第一種情況的時候,函數(shù)就會開始執(zhí)行所有中間件的 process_template_response 方法,并且自下而上在每個中間件中挨個執(zhí)行(當有定義 process_template_response 方法的時候)
當出現(xiàn)第二種情況的時候,函數(shù)就會開始執(zhí)行所有中間件的 process_exception 方法,并且自下而上在每個中間件中挨個執(zhí)行(當有定義 process_exception 方法的時候)
當出現(xiàn)第三種情況的時候,函數(shù)就會自下而上同時執(zhí)行所有中間件中定義的 process_exception 和 process_template_response 方法(在這個時候會優(yōu)先執(zhí)行所有中間件中的process_template_response 方法,再執(zhí)行所有中間件中的process_exception方法)
4、process_response 階段
當 process_request, process_view,views,process_template_response,process_exception 方法都執(zhí)行完成后,開始自下而上從中間件中執(zhí)行 process_response 方法,直到最上層中間件的 process_response 方法執(zhí)行完畢,接著返回給用戶
六、Django 自定義中間件
1、在settings中定義三個中間件
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', 'Middleware.test.m1', 'Middleware.test.m2', 'Middleware.test.m3', ]
2、創(chuàng)建中間件路徑
在項目跟路徑下面創(chuàng)建中間件路徑
./Middleware/test.py
3、定義中間件
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class m1(MiddlewareMixin): def process_request(self, request): print('m1 request') def process_view(self, request, func_view, func_args, func_kwargs): print('m1 view') def process_response(self, request, response): print('m1 response') return response def process_exception(self, request, exception): print('m1 exception') def process_template_response(self, request, response): print('m1 template response') return response class m2(MiddlewareMixin): def process_request(self, request): print('m2 request') def process_view(self, request, func_view, func_args, func_kwargs): print('m2 view') def process_response(self, request, response): print('m2 response') return response def process_exception(self, request, exception): print('m2 exception') def process_template_response(self, request, response): print('m2 template response') return response class m3(MiddlewareMixin): def process_request(self, request): print('m3 request') def process_view(self, request, func_view, func_args, func_kwargs): print('m3 view') def process_response(self, request, response): print('m3 response') return response def process_exception(self, request, exception): print('m3 exception') def process_template_response(self, request, response): print('m3 template response') return response
4、定義視圖函數(shù)
class Foo: def render(self): int('v') return HttpResponse('OK') def middleware(request): #return render(request, 'login.html') #return HttpResponse('middleware') return Foo()
七、一個請求經過中間件的請求周期
由于views視圖函數(shù)中有個報錯需要觸發(fā)中間件中定義的 process_exception 方法,所以便于展示執(zhí)行順序,我去除了具體的報錯內容
m1 request m2 request m3 request m1 view m2 view m3 view m3 template response m2 template response m1 template response m3 exception m2 exception m1 exception m3 response m2 response m1 response
八、結論
大家可根據(jù)自己需求自行編寫中間件,并且測試中間件中每個方法的執(zhí)行順序,總共有5個方法,分別為
process_request
process_view
process_template_response
process_exception
process_response
另外:
Django 官方不建議在中間件層處理 request.POST 數(shù)據(jù),csrf中間件是個例外,因為要全局安全處理用戶token
到此這篇關于Django框架之中間件MiddleWare的實現(xiàn)的文章就介紹到這了,更多相關Django 中間件MiddleWare內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python對Excel按列值篩選并拆分表格到多個文件的代碼
這篇文章主要介紹了Python對Excel按列值篩選并拆分表格到多個文件,本文通過代碼給大家介紹的非常詳細,需要的朋友可以參考下2019-11-11Python數(shù)據(jù)類型詳解(三)元祖:tuple
本文給大家介紹的是Python數(shù)據(jù)類型中的元祖(tuple),簡單的說Tuple,與列表一樣,元素也是不可變的,但與列表不同,在一個元祖可以包含不同類型的元素2016-05-05Python numpy多維數(shù)組實現(xiàn)原理詳解
這篇文章主要介紹了python numpy多維數(shù)組實現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03