深入探索Django中間件的應(yīng)用場(chǎng)景
中間件的應(yīng)用
在之前的文章中,我們已經(jīng)實(shí)現(xiàn)了用戶必須登錄才能投票的限制。然而,如果我們的應(yīng)用中有很多功能都需要用戶先登錄才能執(zhí)行,例如將前面導(dǎo)出Excel報(bào)表和查看統(tǒng)計(jì)圖表的功能都做了必須登錄才能訪問(wèn)的限制,那么我們是不是需要在每個(gè)視圖函數(shù)中添加代碼來(lái)檢查session中是否包含userid的代碼呢?答案是否定的,如果這樣做了,我們的視圖函數(shù)中必然會(huì)充斥著大量的重復(fù)代碼。編程大師 Martin Fowler 曾經(jīng)說(shuō)過(guò):代碼有很多種壞味道,重復(fù)是最壞的一種。在 Python 程序中,我們可以通過(guò)裝飾器來(lái)為函數(shù)提供額外的能力;在 Django 項(xiàng)目中,我們可以把類似于驗(yàn)證用戶是否登錄這樣的重復(fù)性代碼放到 中間件 中。
Django中間件概述
中間件是安插在 Web 應(yīng)用請(qǐng)求和響應(yīng)過(guò)程之間的組件,它在整個(gè) Web 應(yīng)用中扮演了攔截過(guò)濾器的角色,通過(guò)中間件可以攔截請(qǐng)求和響應(yīng),并對(duì)請(qǐng)求和響應(yīng)進(jìn)行過(guò)濾(簡(jiǎn)單的說(shuō)就是執(zhí)行額外的處理)。通常,一個(gè)中間件組件只專注于完成一件特定的事,例如:Django 框架通過(guò) SessionMiddleware 中間件實(shí)現(xiàn)了對(duì) session 的支持,又通過(guò) AuthenticationMiddleware 中間件實(shí)現(xiàn)了基于 session 的請(qǐng)求認(rèn)證。通過(guò)把多個(gè)中間件組合在一起,我們可以完成更為復(fù)雜的任務(wù),Django 框架就是這么做的。
在 Django 項(xiàng)目的配置文件中就包含了對(duì)中間件的配置,代碼如下所示。
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',
]我們稍微為大家解釋一下這些中間件的作用:
CommonMiddleware - 基礎(chǔ)設(shè)置中間件,可以處理以下一些配置參數(shù)。
DISALLOWED_USER_AGENTS- 不被允許的用戶代理(瀏覽器)APPEND_SLASH- 是否追加/USE_ETAG- 瀏覽器緩存相關(guān)
SecurityMiddleware - 安全相關(guān)中間件,可以處理和安全相關(guān)的配置項(xiàng)。
SECURE_HSTS_SECONDS- 強(qiáng)制使用 HTTPS 的時(shí)間SECURE_HSTS_INCLUDE_SUBDOMAINS- HTTPS 是否覆蓋子域名SECURE_CONTENT_TYPE_NOSNIFF- 是否允許瀏覽器推斷內(nèi)容類型SECURE_BROWSER_XSS_FILTER- 是否啟用跨站腳本攻擊過(guò)濾器SECURE_SSL_REDIRECT- 是否重定向到 HTTPS 連接SECURE_REDIRECT_EXEMPT- 免除重定向到 HTTPS
SessionMiddleware - 會(huì)話中間件。
CsrfViewMiddleware - 通過(guò)生成令牌,防范跨請(qǐng)求份偽的造中間件。
XFrameOptionsMiddleware - 通過(guò)設(shè)置請(qǐng)求頭參數(shù),防范點(diǎn)擊劫持攻擊的中間件。
在請(qǐng)求的過(guò)程中,上面的中間件會(huì)按照書寫的順序從上到下執(zhí)行,然后是 URL 解析,最后請(qǐng)求才會(huì)來(lái)到視圖函數(shù);在響應(yīng)的過(guò)程中,上面的中間件會(huì)按照書寫的順序從下到上執(zhí)行,與請(qǐng)求時(shí)中間件執(zhí)行的順序正好相反。
自定義中間件
Django 中的中間件有兩種實(shí)現(xiàn)方式:基于類的實(shí)現(xiàn)方式和基于函數(shù)的實(shí)現(xiàn)方式,后者更接近于裝飾器的寫法。裝飾器實(shí)際上是代理模式的應(yīng)用,將橫切關(guān)注功能(與正常業(yè)務(wù)邏輯沒(méi)有必然聯(lián)系的功能,例如:身份認(rèn)證、日志記錄、編碼轉(zhuǎn)換之類的功能)置于代理中,由代理對(duì)象來(lái)完成被代理對(duì)象的行為并添加額外的功能。中間件對(duì)用戶請(qǐng)求和響應(yīng)進(jìn)行攔截過(guò)濾并增加額外的處理,在這一點(diǎn)上它跟裝飾器是完全一致的,所以基于函數(shù)的寫法來(lái)實(shí)現(xiàn)中間件就跟裝飾器的寫法幾乎一模一樣。
下面我們用自定義的中間件來(lái)實(shí)現(xiàn)用戶登錄驗(yàn)證的功能。
我們可以自定義中間件來(lái)實(shí)現(xiàn)對(duì)登錄狀態(tài)的檢查,如果用戶未登錄的話,就直接跳轉(zhuǎn)到登錄頁(yè)面。下面是一個(gè)簡(jiǎn)單的中間件,用于檢查用戶是否登錄:
"""
middlewares.py
"""
from django.http import JsonResponse
from django.shortcuts import redirect
# 需要登錄才能訪問(wèn)的資源路徑
LOGIN_REQUIRED_URLS = {'/praise/', '/criticize/', '/excel/', '/teachers_data/'}
def check_login_middleware(get_resp):
def wrapper(request, *args, **kwargs):
# 請(qǐng)求的資源路徑在上面的集合中
if request.path in LOGIN_REQUIRED_URLS:
# 會(huì)話中包含 userid 則視為已經(jīng)登錄
if 'userid' in request.session:
return get_resp(request, *args, **kwargs)
# 跳轉(zhuǎn)到登錄頁(yè)面
else:
return redirect('/login/')
return get_resp(request, *args, **kwargs)
return wrapper然后,在項(xiàng)目的配置文件中,將中間件添加到 MIDDLEWARE 列表中即可:
MIDDLEWARE = [
# ...
'path.to.check_login_middleware',
# ...
]這樣,我們就可以在需要登錄才能訪問(wèn)的視圖函數(shù)中添加一個(gè)裝飾器,例如:
@check_login_middleware
def praise(request):
pass這樣就完成了對(duì)登錄狀態(tài)的檢查。
總結(jié)
通過(guò)本文的介紹,我們了解了中間件的應(yīng)用和自定義中間件的實(shí)現(xiàn)方式。在 Django 項(xiàng)目中,中間件的應(yīng)用可以避免大量的重復(fù)代碼,讓我們的代碼更加簡(jiǎn)潔,也更容易維護(hù)。在實(shí)際項(xiàng)目中,我們可以根據(jù)需求自定義不同的中間件,實(shí)現(xiàn)不同的功能。同時(shí),需要注意的是,中間件的執(zhí)行順序也很重要,需要根據(jù)實(shí)際情況來(lái)確定。希望本文對(duì)大家有所幫助,謝謝閱讀!
到此這篇關(guān)于深入探索Django中間件的應(yīng)用場(chǎng)景的文章就介紹到這了,更多相關(guān)Django中間件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python 的matplotlib 畫軌道實(shí)例
今天小編就為大家分享一篇使用python 的matplotlib 畫軌道實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01
pandas進(jìn)行數(shù)據(jù)的交集與并集方式的數(shù)據(jù)合并方法
今天小編就為大家分享一篇pandas進(jìn)行數(shù)據(jù)的交集與并集方式的數(shù)據(jù)合并方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
Python3 venv搭建輕量級(jí)虛擬環(huán)境的步驟(圖文)
這篇文章主要介紹了Python3 venv搭建輕量級(jí)虛擬環(huán)境的步驟(圖文),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Python如何使用隊(duì)列方式實(shí)現(xiàn)多線程爬蟲
這篇文章主要介紹了Python如何使用隊(duì)列方式實(shí)現(xiàn)多線程爬蟲,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
python訪問(wèn)mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法(2則示例)
這篇文章主要介紹了python訪問(wèn)mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了兩種Python操作MySQL數(shù)據(jù)庫(kù)的相關(guān)技巧,需要的朋友可以參考下2016-01-01
Python 實(shí)現(xiàn)LeNet網(wǎng)絡(luò)模型的訓(xùn)練及預(yù)測(cè)
本文將為大家詳細(xì)講解如何使用CIFR10數(shù)據(jù)集訓(xùn)練模型以及用訓(xùn)練好的模型做預(yù)測(cè)。代碼具有一定價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下2021-11-11
OpenCV學(xué)習(xí)記錄python實(shí)現(xiàn)連通域處理函數(shù)
這篇文章主要為大家介紹了OpenCV學(xué)習(xí)記錄python實(shí)現(xiàn)連通域處理函數(shù)cv2.connectedComponentsWithStats()和cv2.connectedComponents()的使用示例詳解2022-06-06
Python 更快進(jìn)行探索性數(shù)據(jù)分析的四個(gè)方法
今天我給大家分享幾種更快的探索性數(shù)據(jù)分析方法,它們可以進(jìn)一步加速 EDA。 我們以一個(gè)學(xué)生考試成績(jī)的例子,創(chuàng)建一個(gè)如下所示的 DataFrame 并繼續(xù)操作。歡迎收藏學(xué)習(xí),喜歡點(diǎn)贊支持2021-11-11

