Django自定義中間件實現(xiàn)全鏈路操作日志記錄
一、中間件
介紹
在 Django 中,中間件(Middleware)是一組輕量級、底層的插件系統(tǒng),用于全局地改變 Django 的輸入和輸出。中間件可以在請求被處理之前和響應(yīng)返回之前執(zhí)行代碼,從而實現(xiàn)各種功能,例如跨域資源共享(CORS)、用戶認(rèn)證、日志記錄等。
激活中間件
若要激活中間件,需要添加到settings.MIDDLEWARE中
- 每個中間件組件由字符串表示:指向中間件工廠類的完整 Python 路徑。
- 需求注意中間件的添加順序。因為中間件有執(zhí)行順序,而且中間件之間可能有依賴關(guān)系。
- 中間件的全局執(zhí)行順序
- 請求階段:按
settings.MIDDLEWARE中從上到下的順序執(zhí)行。 - 視圖處理:請求到達(dá)視圖函數(shù)。
- 響應(yīng)階段:按
settings.MIDDLEWARE中從下到上的順序執(zhí)行。
- 請求階段:按
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware", # CORS跨域支持
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware", # I18N多語言支持,注意放置順序
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
# "myapp_system.operate_log.services.OperateLogMiddleware", # 操作日志開關(guān):如果數(shù)據(jù)庫磁盤IO性能一般,建議關(guān)閉
]生命周期
中間件生命周期
- 請求階段:
process_request(request):在視圖函數(shù)被調(diào)用之前執(zhí)行,用于處理請求。如果返回HttpResponse對象,則后續(xù)的中間件和視圖不會被調(diào)用,直接返回響應(yīng)。 - 視圖階段:
process_view(request, view_func, view_args, view_kwargs):在視圖函數(shù)被調(diào)用之前執(zhí)行,可以用于根據(jù)視圖函數(shù)的參數(shù)或請求信息進(jìn)行額外處理。 - 響應(yīng)階段:
process_response(request, response):在視圖函數(shù)返回響應(yīng)后執(zhí)行,用于處理響應(yīng)對象,可以修改響應(yīng)內(nèi)容或響應(yīng)頭。 - 異常階段:
process_exception(request, exception):當(dāng)視圖函數(shù)拋出異常時執(zhí)行,用于處理異常并返回一個HttpResponse對象。
內(nèi)置中間件示例
django.contrib.auth.middleware.AuthenticationMiddleware:Django內(nèi)置的認(rèn)證中間件,實現(xiàn)將user屬性添加到每個傳入的HttpRequest對象中,表示當(dāng)前已登錄的用戶
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
if not hasattr(request, "session"):
raise ImproperlyConfigured(
"The Django authentication middleware requires session "
"middleware to be installed. Edit your MIDDLEWARE setting to "
"insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
)
request.user = SimpleLazyObject(lambda: get_user(request))二、自定義中間件
中間件鉤子函數(shù)
process_view()中間件鉤子函數(shù)
- 語法:
process_view(request, view_func, view_args, view_kwargs) - 調(diào)用順序:process_view() 只在 Django 調(diào)用視圖前被調(diào)用。
- 返回
- 如果它返回
None,Django 將繼續(xù)處理這個請求,執(zhí)行任何其他的process_view(),然后執(zhí)行相應(yīng)的視圖。 - 如果它返回
HttpResponse對象,Django 不會去影響調(diào)用相應(yīng)的視圖;它會將響應(yīng)中間件應(yīng)用到HttpResponse并返回結(jié)果。
- 如果它返回
基于類的中間件
基于類的自定義中間件格式
- 語句
response = self.get_response(request),將__call__()方法中的代碼分為兩部分
class SimpleMiddleware:
def __init__(self, get_response):
# 執(zhí)行一次性配置和初始化工作
self.get_response = get_response
def __call__(self, request):
# 每個請求調(diào)用一次,在視圖函數(shù)被調(diào)用之前執(zhí)行
response = self.get_response(request)
# 每個請求調(diào)用一次,在視圖函數(shù)被調(diào)用之后執(zhí)行
return response三、實戰(zhàn)案例
操作日志功能
通過自定義中間件,實現(xiàn)Django操作日志記錄功能
- 第1步:定義類
OperateLogMiddleware,方法__init__()中,添加exclude_urls排除不需要記錄的URL的列表,和一個字典log_data用于臨時存放日志信息。

- 第2步:在執(zhí)行視圖函數(shù)之前,向字典
log_data記錄請求方法、請求路徑、操作IP、瀏覽器Agent信息等

- 第3步:在執(zhí)行視圖函數(shù)之后,向字典
log_data記錄用戶ID、業(yè)務(wù)狀態(tài)碼、HTTP狀態(tài)碼、響應(yīng)數(shù)據(jù)、返回結(jié)果和執(zhí)行時間

- 第4步:
process_view()中間件鉤子函數(shù)中,向字典log_data記錄視圖名稱、Action名稱、資源ID

第5步:字典log_data記錄的操作日志信息,通過Celery異步任務(wù),寫入數(shù)據(jù)庫。實現(xiàn)操作日志記錄功能。
代碼運行效果:

參考資料
到此這篇關(guān)于Django自定義中間件實現(xiàn)全鏈路操作日志記錄的文章就介紹到這了,更多相關(guān)django自定義中間件全鏈路內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用numpy轉(zhuǎn)換成cupy利用GPU執(zhí)行錯誤
在使用PyInstaller打包Python程序時,可能會遇到缺少模塊的錯誤,尤其是在將Numpy轉(zhuǎn)換為CuPy以利用GPU加速時,如果遇到ModuleNotFoundError,表明PyInstaller沒有包含一些隱式導(dǎo)入的包,解決方法是手動將缺失的包添加到打包目錄中2024-09-09
YOLOv5改進(jìn)之添加SE注意力機(jī)制的詳細(xì)過程
作為當(dāng)前先進(jìn)的深度學(xué)習(xí)目標(biāo)檢測算法YOLOv5,已經(jīng)集合了大量的trick,但是還是有提高和改進(jìn)的空間,針對具體應(yīng)用場景下的檢測難點,可以不同的改進(jìn)方法,下面這篇文章主要給大家介紹了關(guān)于YOLOv5改進(jìn)之添加SE注意力機(jī)制的相關(guān)資料,需要的朋友可以參考下2022-08-08
利用Python的Flask框架來構(gòu)建一個簡單的數(shù)字商品支付解決方案
這篇文章主要介紹了利用Python的Flask框架來構(gòu)建一個簡單的數(shù)字商品支付解決方案,文中用極簡的代碼展示了一個flask框架下的支付模版,需要的朋友可以參考下2015-03-03
PyTorch之torch.randn()如何創(chuàng)建正態(tài)分布隨機(jī)數(shù)
這篇文章主要介紹了PyTorch之torch.randn()如何創(chuàng)建正態(tài)分布隨機(jī)數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
Python實現(xiàn)的多進(jìn)程和多線程功能示例
這篇文章主要介紹了Python實現(xiàn)的多進(jìn)程和多線程功能,結(jié)合實例形式分析了Python多線程與多進(jìn)程實現(xiàn)分布式系統(tǒng)功能相關(guān)操作技巧,需要的朋友可以參考下2018-05-05
python?裝飾器(Decorators)原理說明及操作代碼
裝飾器(Decorators)是 Python 的一個重要部分,本文由淺入深給大家介紹了python?裝飾器Decorators原理,感興趣的朋友跟隨小編一起看看吧2021-12-12

