Django中間件
Django1.9版本以后,我們從瀏覽器發(fā)出一個(gè)請(qǐng)求 Request,得到一個(gè)響應(yīng)后的內(nèi)容 HttpResponse ,這個(gè)請(qǐng)求傳遞到 Django的過程如下:
也就是說,每一個(gè)請(qǐng)求都是先通過中間件中的 process_request 函數(shù),這個(gè)函數(shù)返回 None 或者 HttpResponse 對(duì)象,如果返回前者,繼續(xù)處理其它中間件,如果返回一個(gè) HttpResponse,就處理中止,返回到網(wǎng)頁上。
中間件(類)的幾種方法
中間件可以定義的幾種方法,分別是:
process_request(self,request) : 在處理url請(qǐng)求之前執(zhí)行
process_view(self, request, callback, callback_args,
callback_kwargs) : 調(diào)用視圖之前執(zhí)行
process_template_response(self,request,response) : 只有當(dāng)views函數(shù)中返回的對(duì)象中具有render方法,才會(huì)直接調(diào)用
process_response(self, request, response) : 在響應(yīng)返回瀏覽器之前調(diào)用
自定義中間件
在Django中我們可以自己寫一個(gè)繼承了MiddlewareMixin的類,來實(shí)現(xiàn)自定義中間件。通過from django.urls.deprecation import MiddlewareMixin導(dǎo)入MiddlewareMixin。
為中間件創(chuàng)建一個(gè)目錄Middle,并在Middle目錄下創(chuàng)建middle1.py:
from django.utils.deprecation import MiddlewareMixin
class middle11(MiddlewareMixin):
def process_request(self, request):
print("中間件1請(qǐng)求")
def process_response(self, request, response):
print("中間件1返回")
return response
class middle2(MiddlewareMixin):
def process_request(self, request):
print("中間件2請(qǐng)求")
def process_response(self, request, response):
print("中間件2返回")
return response
class middle3(MiddlewareMixin):
def process_request(self, request):
print("中間件3請(qǐng)求")
def process_response(self, request, response):
print("中間件3返回")
return response
在項(xiàng)目目錄下的settings.py文件的MIDDLEWARE中添加如下三行:
'Middle.middle1.middle11',
'Middle.middle1.middle2',
'Middle.middle1.middle3',
當(dāng)我們?cè)跒g覽器中訪問一個(gè)頁面的時(shí)候在控制臺(tái)就會(huì)看到如下的結(jié)果:
從這里也向我們證實(shí)了當(dāng)一個(gè)請(qǐng)求進(jìn)來的時(shí)候,會(huì)通過所有的中間件處理,并且當(dāng)請(qǐng)求獲得相應(yīng)時(shí)也會(huì)通過中間件去處理。
中間件應(yīng)用場(chǎng)景
由于中間件工作在 視圖函數(shù)執(zhí)行前、執(zhí)行后適合所有的請(qǐng)求/一部分請(qǐng)求做批量處理。
1、做IP限制
放在 中間件類的列表中,阻止某些IP訪問了;
2.URL訪問過濾
如果用戶訪問的是login視圖(放過)
如果訪問其他視圖(需要檢測(cè)是不是有session已經(jīng)有了放行,沒有返回login),這樣就省得在 多個(gè)視圖函數(shù)上寫裝飾器了!
3、緩存(CDN)
客戶端請(qǐng)求來了,中間件去緩存看看有沒有數(shù)據(jù),有直接返回給用戶,沒有再去邏輯層 執(zhí)行視圖函數(shù)
注意:項(xiàng)目目錄下MIDDLEWARE中'django.middleware.csrf.CsrfViewMiddleware',為用戶實(shí)現(xiàn)防止跨站請(qǐng)求偽造的功能,在之前我們都是將它注釋掉的,因?yàn)槲覀內(nèi)绻蛔⑨尩粼诒韱翁峤坏臅r(shí)候就會(huì)報(bào)forbidden的錯(cuò)誤,但是如果我們又要用到防止跨域請(qǐng)求,又不要報(bào)錯(cuò)我們只需要在表單<from>標(biāo)簽中加入{% csrf_token %}即可解決這個(gè)問題。
練習(xí):
1.利用用中間件,實(shí)現(xiàn)讓所有頁面都必須在進(jìn)行用戶登錄后才能訪問qin
2.中間件統(tǒng)計(jì),某個(gè)網(wǎng)頁的訪問次數(shù)。