中間件是Django處理請求和響應處理過程中的一個鈎子,它比較輕量級,但是可以用來改變Django全局的的輸入和輸出。
每一個中間件一般都用來做一些特殊的功能,可以添加多個中間件來實作更多的功能。
今天一起看一下Django的中間件是如何工作的,如何激活,并且自己寫一個中間件。Django還内置了一些中間件,可以拿來即用。參考
内置中間件中間件寫法參考
中間件可以以函數的形式來寫,如下:
def simple_middleware(get_response):
# One-time configuration and initialization.
# 配置和初始化的工作,隻執行一次
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
# 在view被調用之前,請求還未加工時執行
response = get_response(request)
# Code to be executed for each request/response after
# the view is called.
# 在請求/響應處理完畢後調用的代碼
return response
return middleware
- 函數必須傳遞的參數為
get_response
- 傳回值必須為
middleware
除了函數形式為,更多的寫法一般是寫成類的形式。
class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
# 代碼初始化時候執行,可以做一次性的配置
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
# 在view被調用之前,請求還未加工時執行
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called.
# 請求/響應被處理之後執行
return response
-
方法隻執行一次__init__
-
方法可以執行多次__call__
标記中間件為不可用狀态
有時候,你想在項目啟動時判斷是否要用這個中間件,這種情況下,在你的init方法中,抛出MiddlewareNotUsed異常。Django就會移除這個中間件,如果有日志開啟的話,
DEBUG=True
, 你也可以看到日志輸出的資訊。
激活中間件
如果要激活一個中間件,把它添加到項目
settings.py
中的MIDDLEWARE部分。
裡面的配置,每一個中間件都是以字元串形式來表示,并且要提供完整的路徑。如下:
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',
'libs.middleware.HandleExceptionMiddleware', # 處理視圖函數異常
]
建議至少使用一個中間件,django.middleware.common.CommonMiddleware
中間件的順序也很重要,有時候某個中間件需要依賴另外一個中間件的執行結果才可以生效。例如:
AuthenticationMiddleware
存儲使用者的認證資訊在Session中,是以它必須在
SessionMiddleware.
中間件之後。
中間件的執行順序是從數組的,
從上往下
執行。但是對于響應則是從下往上執行。
中間件的其它鈎子
除了基本的請求/響應處理的那個中間件,你還可以添加另外三個特殊的方法。
- process_view(request, view_func, view_args, view_kwargs) 在Django調用view之前執行,可以傳回None或者HttpResponse對象。如果傳回的是None,Django會繼續執行直到找到合适的視圖為止,如果傳回的是HttpResponse對象,Django就停止執行,然後傳回HttpResponse結果。
- process_exception(request, exception) 當view抛出異常的時候,會觸發Django調用這個函數。可以傳回None或者HttpResponse對象。同上面
- process_template_response(request, response) 當view結束執行的時候調用,如果響應有
方法,代表它是個 TemplateResponse。這個函數必須要傳回一個響應對象有render()
方法。render()
最後
中間件還有很多功能,等待大家一起去發掘。