Django框架之中間件MiddleWare的實(shí)現(xiàn)
一、中間件
Middleware是Django請(qǐng)求/響應(yīng)處理的插件框架。它是一個(gè)輕巧的低級(jí)"插件"系統(tǒng),用于全局改變Django的輸入或輸出。
每個(gè)中間件組件負(fù)責(zé)執(zhí)行某些特定功能。例如,Django包含一個(gè)中間件組件 AuthenticationMiddleware,它將用戶與使用會(huì)話的請(qǐng)求相關(guān)聯(lián)。
該文檔介紹了中間件的工作原理,如何激活中間件以及如何編寫自己的中間件。Django附帶了一些你可以直接使用的內(nèi)置中間件。它們記錄在內(nèi)置中間件參考中
二、激活中間件
要激活中間件,請(qǐng)將其添加到MIDDLEWARE Django設(shè)置中的列表中
如下,我激活了三個(gè)中間件 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',
]
三、中間件請(qǐng)求和響應(yīng)
在請(qǐng)求階段,調(diào)用views之前,django按照MIDDLEWARE_CLASSES中定義的順序從上到下調(diào)用中間件。
在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',
]
一個(gè)中間件最少有一個(gè)process_request hooks和一個(gè)process_response hooks,前者是用來處理請(qǐng)求的,后者是用來處理響應(yīng)的
那除了必須的兩個(gè)hooks以外,還有其他三個(gè)hooks,分別是 process_view, process_exception, process_template_response
process_view 主要是用來執(zhí)行middleware中具體的處理函數(shù),如中間件請(qǐng)求中所說,是從上到下的hooks,表示process_view在views視圖函數(shù)之前執(zhí)行
process_exception 一般情況下不會(huì)執(zhí)行,只有在views視圖函數(shù)中出現(xiàn)exception異常時(shí),才會(huì)執(zhí)行;如中間件請(qǐng)求中所說,是從下到上的hooks,表示processs_exception在views視圖函數(shù)之后執(zhí)行,也就是views視圖函數(shù)出錯(cuò)之后,才會(huì)執(zhí)行
processs_template_response 一般情況下也不會(huì)執(zhí)行,也就是說,只有views中的函數(shù)返回對(duì)象中具有render方法,它才會(huì)執(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 階段
當(dāng)一個(gè)用戶發(fā)起請(qǐng)求后,該請(qǐng)求會(huì)經(jīng)過上述的所有中間件,并且自上而下執(zhí)行;先執(zhí)行所有中間件的 process_request方法,該方法如果返回HttpResponse,則執(zhí)行從當(dāng)前的中間件向上執(zhí)行 process_responsse,如果返回None,則接著向下執(zhí)行 process_request
2、process_view 階段
當(dāng)該用戶的請(qǐng)求執(zhí)行完所有中間件 process_request 方法后,如果返回都為None,那么接下來會(huì)執(zhí)行所有中間件的 process_view 方法,如果其中一個(gè) process_view 返回HttpResponse,則會(huì)跳過接下來所有中間件的 process_view,直接會(huì)從最下面的process_response自下而上執(zhí)行,如果process_view返回None,則會(huì)繼續(xù)向下執(zhí)行
3、views 階段
當(dāng)該用戶的請(qǐng)求執(zhí)行完所有的process_request和process_view階段,并且沒有返回HttpResponse;換句話說,返回的都是None,那么這個(gè)時(shí)候就會(huì)到達(dá)views視圖函數(shù)
在這里,可能會(huì)有三種可能性
(1) views中的函數(shù)返回對(duì)象中具有render方法
(2) views中的函數(shù)產(chǎn)生異常
(3) views中的函數(shù)返回對(duì)象中具有render方法,并且views中的函數(shù)產(chǎn)生異常
當(dāng)出現(xiàn)第一種情況的時(shí)候,函數(shù)就會(huì)開始執(zhí)行所有中間件的 process_template_response 方法,并且自下而上在每個(gè)中間件中挨個(gè)執(zhí)行(當(dāng)有定義 process_template_response 方法的時(shí)候)
當(dāng)出現(xiàn)第二種情況的時(shí)候,函數(shù)就會(huì)開始執(zhí)行所有中間件的 process_exception 方法,并且自下而上在每個(gè)中間件中挨個(gè)執(zhí)行(當(dāng)有定義 process_exception 方法的時(shí)候)
當(dāng)出現(xiàn)第三種情況的時(shí)候,函數(shù)就會(huì)自下而上同時(shí)執(zhí)行所有中間件中定義的 process_exception 和 process_template_response 方法(在這個(gè)時(shí)候會(huì)優(yōu)先執(zhí)行所有中間件中的process_template_response 方法,再執(zhí)行所有中間件中的process_exception方法)
4、process_response 階段
當(dāng) process_request, process_view,views,process_template_response,process_exception 方法都執(zhí)行完成后,開始自下而上從中間件中執(zhí)行 process_response 方法,直到最上層中間件的 process_response 方法執(zhí)行完畢,接著返回給用戶
六、Django 自定義中間件
1、在settings中定義三個(gè)中間件
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)建中間件路徑
在項(xià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()
七、一個(gè)請(qǐng)求經(jīng)過中間件的請(qǐng)求周期
由于views視圖函數(shù)中有個(gè)報(bào)錯(cuò)需要觸發(fā)中間件中定義的 process_exception 方法,所以便于展示執(zhí)行順序,我去除了具體的報(bào)錯(cuò)內(nèi)容
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
八、結(jié)論
大家可根據(jù)自己需求自行編寫中間件,并且測(cè)試中間件中每個(gè)方法的執(zhí)行順序,總共有5個(gè)方法,分別為
process_request
process_view
process_template_response
process_exception
process_response
另外:
Django 官方不建議在中間件層處理 request.POST 數(shù)據(jù),csrf中間件是個(gè)例外,因?yàn)橐职踩幚碛脩魌oken
到此這篇關(guān)于Django框架之中間件MiddleWare的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Django 中間件MiddleWare內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在python tkinter界面中添加按鈕的實(shí)例
今天小編就為大家分享一篇在python tkinter界面中添加按鈕的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
關(guān)于PyCharm安裝后修改路徑名稱使其可重新打開的問題
這篇文章主要介紹了關(guān)于PyCharm安裝后修改路徑名稱使其可重新打開的問題,本文通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Python深度學(xué)習(xí)pytorch實(shí)現(xiàn)圖像分類數(shù)據(jù)集
這篇文章主要為大家講解了關(guān)于Python深度學(xué)習(xí)中pytorch實(shí)現(xiàn)圖像分類數(shù)據(jù)集的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
在Pandas?DataFrame中插入一列的方法實(shí)例
在敲代碼的過程中,老是會(huì)遇到在Dataframe中新添加一列的情況,所以下面這篇文章主要給大家介紹了關(guān)于如何在Pandas?DataFrame中插入一列的方法實(shí)的相關(guān)資料,需要的朋友可以參考下2022-03-03
pytorch中常用的乘法運(yùn)算及相關(guān)的運(yùn)算符(@和*)
pytorch是深度學(xué)習(xí)框架,而深度學(xué)習(xí)其實(shí)本質(zhì)就是一大堆矩陣乘法,最后用來模擬一個(gè)高維擬合函數(shù),下面這篇文章主要給大家介紹了關(guān)于pytorch中常用的乘法運(yùn)算及相關(guān)的運(yùn)算符(@和*)的相關(guān)資料,需要的朋友可以參考下2022-01-01
Python合并字典鍵值并去除重復(fù)元素的實(shí)例
下面小編就為大家?guī)硪黄狿ython合并字典鍵值并去除重復(fù)元素的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12
Python SVM(支持向量機(jī))實(shí)現(xiàn)方法完整示例
這篇文章主要介紹了Python SVM(支持向量機(jī))實(shí)現(xiàn)方法,結(jié)合完整實(shí)例形式分析了基于Python實(shí)現(xiàn)向量機(jī)SVM算法的具體步驟與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-06-06
Python下使用Trackbar實(shí)現(xiàn)繪圖板
這篇文章主要為大家詳細(xì)介紹了Python下使用Trackbar實(shí)現(xiàn)繪圖板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10

