文章目錄
- 一、中間件
- 介紹
- 激活中間件
- 生命周期
- 二、自定義中間件
- 中間件鉤子函數
- 基于類的中間件
- 三、實戰案例
- 操作日志功能
- 參考資料
一、中間件
介紹
在 Django 中,中間件(Middleware)是一組輕量級、底層的插件系統,用于全局地改變 Django 的輸入和輸出。中間件可以在請求被處理之前和響應返回之前執行代碼,從而實現各種功能,例如跨域資源共享(CORS)、用戶認證、日志記錄等。
激活中間件
若要激活中間件,需要添加到settings.MIDDLEWARE
中
- 每個中間件組件由字符串表示:指向中間件工廠類的完整 Python 路徑。
- 需求注意中間件的添加順序。因為中間件有執行順序,而且中間件之間可能有依賴關系。
- 中間件的全局執行順序
- 請求階段:按
settings.MIDDLEWARE
中從上到下的順序執行。 - 視圖處理:請求到達視圖函數。
- 響應階段:按
settings.MIDDLEWARE
中從下到上的順序執行。
- 請求階段:按
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", # 操作日志開關:如果數據庫磁盤IO性能一般,建議關閉
]
生命周期
中間件生命周期
- 請求階段:
process_request(request)
:在視圖函數被調用之前執行,用于處理請求。如果返回HttpResponse
對象,則后續的中間件和視圖不會被調用,直接返回響應。 - 視圖階段:
process_view(request, view_func, view_args, view_kwargs)
:在視圖函數被調用之前執行,可以用于根據視圖函數的參數或請求信息進行額外處理。 - 響應階段:
process_response(request, response)
:在視圖函數返回響應后執行,用于處理響應對象,可以修改響應內容或響應頭。 - 異常階段:
process_exception(request, exception)
:當視圖函數拋出異常時執行,用于處理異常并返回一個HttpResponse
對象。
內置中間件示例
django.contrib.auth.middleware.AuthenticationMiddleware
:Django內置的認證中間件,實現將user
屬性添加到每個傳入的HttpRequest
對象中,表示當前已登錄的用戶
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))
二、自定義中間件
中間件鉤子函數
process_view()
中間件鉤子函數
- 語法:
process_view(request, view_func, view_args, view_kwargs)
- 調用順序:process_view() 只在 Django 調用視圖前被調用。
- 返回
- 如果它返回
None
,Django 將繼續處理這個請求,執行任何其他的process_view()
,然后執行相應的視圖。 - 如果它返回
HttpResponse
對象,Django 不會去影響調用相應的視圖;它會將響應中間件應用到HttpResponse
并返回結果。
- 如果它返回
基于類的中間件
基于類的自定義中間件格式
- 語句
response = self.get_response(request)
,將__call__()
方法中的代碼分為兩部分
class SimpleMiddleware:def __init__(self, get_response):# 執行一次性配置和初始化工作self.get_response = get_responsedef __call__(self, request):# 每個請求調用一次,在視圖函數被調用之前執行response = self.get_response(request)# 每個請求調用一次,在視圖函數被調用之后執行return response
三、實戰案例
操作日志功能
通過自定義中間件,實現Django操作日志記錄功能
-
第1步:定義類
OperateLogMiddleware
,方法__init__()
中,添加exclude_urls
排除不需要記錄的URL的列表,和一個字典log_data
用于臨時存放日志信息。
-
第2步:在執行視圖函數之前,向字典
log_data
記錄請求方法、請求路徑、操作IP、瀏覽器Agent信息等
- 第3步:在執行視圖函數之后,向字典
log_data
記錄用戶ID、業務狀態碼、HTTP狀態碼、響應數據、返回結果和執行時間
- 第4步:
process_view()
中間件鉤子函數中,向字典log_data
記錄視圖名稱、Action名稱、資源ID
第5步:字典log_data
記錄的操作日志信息,通過Celery異步任務,寫入數據庫。實現操作日志記錄功能。
代碼運行效果:
查看完整代碼:下載地址
參考資料
- Django 自定義中間件
- Django 中間件
您正在閱讀的是《Django從入門到實戰》專欄!關注不迷路~