Python Django中間件使用原理及流程分析
一、什么是Django中間件
Django 中間件是用來處理Django的請求request和響應(yīng)response的框架級(jí)別的鉤子,它是一個(gè)輕量,低級(jí)別的插件系統(tǒng),用于全局范圍內(nèi)改變Django的輸入,輸出。每個(gè)中間件組件都負(fù)責(zé)做一些特定的功能。
說的直白一點(diǎn)是中間件就是幫我們程序員在視圖函數(shù)執(zhí)行之前和執(zhí)行之后都可以一些額外的操作,它是一個(gè)自定義的類,類中定義了幾個(gè)方法,Django框架會(huì)在請求的特定時(shí)間去執(zhí)行這些方法。
二、Django中間件的定義規(guī)則
1、 自定義中間件的規(guī)則
(1)要繼承MIDDLEWAREMIXIN類
from django.utils.deprecation import MiddlewareMixin
?。?)要重寫父類方法
父類的五個(gè)方法(主要process_request process_response)
?。?)process_request(self,request)
*主要方法。請求剛進(jìn)來時(shí),執(zhí)行視圖函數(shù)之前調(diào)用。(無return)
1.中間件的process_request方法是在執(zhí)行視圖函數(shù)之前執(zhí)行的
2.當(dāng)配置中間件時(shí),會(huì)按照MIDDLEWARE的注冊順序,也就是列表的索引值,從前到后依次執(zhí)行的。
3.不同中間件之間傳遞的request都是同一個(gè)對(duì)象。
?。?)process_view(self,request,view_func,view_args,view_kwargs)
*URL路由匹配成功后,執(zhí)行視圖函數(shù)之前調(diào)用,拿到視圖函數(shù)對(duì)象,及其所有參數(shù)。(無return)
''' process_view(self, request, view_func, view_args, view_kwargs) request是HttpRequest對(duì)象。 view_func是Django即將使用的視圖函數(shù)。 (它是實(shí)際的函數(shù)對(duì)象,而不是函數(shù)的名稱作為字符串。) view_args是將傳遞給視圖的位置參數(shù)的列表. view_kwargs是將傳遞給視圖的關(guān)鍵字參數(shù)的字典。 view_args和view_kwargs都不包含第一個(gè)視圖參數(shù)(request)。 '''
(3)process_template_response(self,request,response)
*很少用。執(zhí)行了render()渲染方法后調(diào)用。(有return)
?。?)process_exception(self,request,exception)
執(zhí)行視圖函數(shù)中遇到異常時(shí)調(diào)用。(無return)
*該方法有兩個(gè)參數(shù):
一個(gè)是httpresponse對(duì)象
一個(gè)是視圖函數(shù)產(chǎn)生的exception對(duì)象
這個(gè)函數(shù)只有在視圖函數(shù)拋出異常才可以執(zhí)行,它返回none或者h(yuǎn)ttpresponse對(duì)象,如果是httpresponse對(duì)象,django將調(diào)用模板和中間件中的process_reponse方法,并將返回給瀏覽器,否則默認(rèn)處理異常,如果返回none,則交給下一個(gè)中間件的process_exception方法來處理執(zhí)行,它的執(zhí)行順序也是按照中間件注冊順序的倒序執(zhí)行。
?。?)process_response(self,request,response)
主要方法。執(zhí)行視圖函數(shù)結(jié)束之后有響應(yīng)時(shí)調(diào)用。(有return)
返回值可以是一個(gè)NONE,或者HttpResponse對(duì)象,如果是none,繼續(xù)按照django定義的向下執(zhí)行,交給下個(gè)中間件處理,如果返回是Httpresponse對(duì)象,django將不執(zhí)行視圖函數(shù),則直接將該對(duì)象返回給用戶。
?。?)將自定義中間件類添加到setting.py文件中的MIDDLEWARE配置項(xiàng)里
setting.py
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', # 自定義 在對(duì)應(yīng)app內(nèi)創(chuàng)建一個(gè) my_middleware.py文件,然后定義類名為Middleware的中間件 'app.my_middleware.Middleware', ] # 白名單路徑,不需要做登陸就能訪問的頁面 WHITE_LIST = ['/login/', '/logout/']
MIDDLEWARE是一個(gè)列表,列表中是一個(gè)個(gè)字符串,這些字符串其實(shí)是類,也就是中間件。
三、代碼實(shí)現(xiàn)
my_middleware.py
from django.utils.deprecation import MiddlewareMixin # 導(dǎo)入中間間模塊 from django.shortcuts import redirect # 返回頁面模塊 from middlewareDemo import settings # 導(dǎo)入白名單 class Middleware(MiddlewareMixin): # 認(rèn)證中間件 def process_request(self, request): """ 請求來之前判斷是否已經(jīng)登錄 :param request: :return: """ white_list = settings.WHITE_LIST if request.path in white_list: return None # 如果是白名單的路徑,直接跳過 if not request.user.is_authenticated: # 獲取用戶是否登陸 return redirect('/login/') def process_response(self, request, response): """ 不管是何執(zhí)行結(jié)果,都會(huì)返回相應(yīng)的HttpResonse對(duì)象 :param request: :param response: :return: """ print('m1.process_response') return response def process_exception(self, request, exception): """ 出現(xiàn)異常才會(huì)被調(diào)用進(jìn)行異常處理 :param request: :param exception: :return: """ print('m1.process_exception')
四、中間件的使用場景
1.做IP限制
放在中間件類的列表中,阻止某些ip訪問;
2.URL訪問過濾
如果用戶訪問的是logo視圖(放過)
如果訪問其他視圖,需要檢測是否已經(jīng)有session,已經(jīng)有了放行,如果沒有返回login,這樣就省的在多個(gè)視圖函數(shù)上寫裝飾器了!
3.緩存
客戶端請求來了,中間件去緩存看看有沒有數(shù)據(jù),有直接返回給用戶,沒有再去邏輯層執(zhí)行視圖函數(shù)
4、CSRF
Django項(xiàng)目中默認(rèn)啟用了csrf保護(hù),每次請求時(shí)通過CSRF中間件檢查請求中是否有正確token值
五、Django中間件與裝飾器的區(qū)別
1、Django 中間件:在視圖函數(shù)執(zhí)行之前先去進(jìn)行處理,在視圖函數(shù)執(zhí)行之后再去進(jìn)行收尾工作。不會(huì)區(qū)分是哪個(gè)視圖,所有的視圖統(tǒng)統(tǒng)一視同仁,都會(huì)執(zhí)行之前進(jìn)行處理或請求之后進(jìn)行處理。
在Django創(chuàng)建的時(shí)候,Django默認(rèn)會(huì)給我們加6個(gè)中間件。“比如session和csrf,在視圖函數(shù)執(zhí)行前,我們就需要對(duì)它進(jìn)行處理,可以使用裝飾器來做,也可以使用中間件來處理?!?/p>
2、裝飾器:主要是作用域問題。如果給視圖函數(shù)上面添加裝飾器,它能夠保證這個(gè)視圖的方法在執(zhí)行之前或執(zhí)行之后被執(zhí)行。但是它僅僅適用于哪些視圖添加裝飾器,那些視圖會(huì)有這些作用。
如果是做一個(gè)普遍的處理,不去區(qū)分視圖的話,就用middleware避免編寫重復(fù)功能的代碼,本質(zhì)上就是一個(gè)自定義類,類中定義了幾個(gè)方法,Django框架會(huì)在請求的特定的時(shí)間去執(zhí)行這些方法。
可以用于登錄時(shí)的黑名單驗(yàn)證。
如果需要對(duì)特殊視圖進(jìn)行處理,可以使用裝飾器。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
計(jì)算機(jī)二級(jí)python學(xué)習(xí)教程(3) python語言基本數(shù)據(jù)類型
這篇文章主要為大家詳細(xì)介紹了計(jì)算機(jī)二級(jí)python學(xué)習(xí)教程的第3篇,python語言基本數(shù)據(jù)類型,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05利用python如何處理百萬條數(shù)據(jù)(適用java新手)
這篇文章主要給大家介紹了關(guān)于利用python如何處理百萬條數(shù)據(jù)的相關(guān)資料,本文的教程非常適用于java新手,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-06-06Python中l(wèi)ogging日志庫實(shí)例詳解
這篇文章主要介紹了Python常用庫logging日志庫的實(shí)例代碼,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02Python獲取時(shí)光網(wǎng)電影數(shù)據(jù)的實(shí)例代碼
這篇文章主要介紹了Python獲取時(shí)光網(wǎng)電影數(shù)據(jù),基本原理是先通過requests庫,通過時(shí)光網(wǎng)自帶的電影數(shù)據(jù)API接口,獲取到指定的電影數(shù)據(jù),本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Python?isdigit()函數(shù)判斷字符串是否全都是數(shù)字字符示例
這篇文章主要為大家介紹了Python判斷字符串是否全都是數(shù)字字符示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Python 獲取numpy.array索引值的實(shí)例
今天小編就為大家分享一篇Python 獲取numpy.array索引值的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12解決python gdal投影坐標(biāo)系轉(zhuǎn)換的問題
今天小編就為大家分享一篇解決python gdal投影坐標(biāo)系轉(zhuǎn)換的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01Python+Socket實(shí)現(xiàn)基于TCP協(xié)議的客戶與服務(wù)端中文自動(dòng)回復(fù)聊天功能示例
這篇文章主要介紹了Python+Socket實(shí)現(xiàn)基于TCP協(xié)議的客戶與服務(wù)端中文自動(dòng)回復(fù)聊天功能,結(jié)合實(shí)例形式分析了Python+Socket實(shí)現(xiàn)帶自動(dòng)回復(fù)功能的TCP聊天程序相關(guān)操作方法與注意事項(xiàng),需要的朋友可以參考下2017-08-08