天天看點

Django(14):Django 中間件

Django 中間件是修改 Django request 或者 response 對象的鈎子,可以了解為是介于 HttpRequest 與 HttpResponse 處理之間的一道處理過程。

浏覽器從請求到響應的過程中,Django 需要通過很多中間件來處理,可以看如下圖所示:

Django(14):Django 中間件

Django 中間件作用:

修改請求,即傳送到 view 中的 HttpRequest 對象。

修改響應,即 view 傳回的 HttpResponse 對象。

中間件元件配置在 settings.py 檔案的 MIDDLEWARE 選項清單中。

配置中的每個字元串選項都是一個類,也就是一個中間件。

Django 預設的中間件配置:

中間件可以定義四個方法,分别是:

自定義中間的步驟:

在 app 目錄下建立一個 py 檔案,名字自定義,并在該 py 檔案中導入 MiddlewareMixin:

Django(14):Django 中間件

自定義的中間件類,要繼承父類 MiddlewareMixin:

在 settings.py 中的 MIDDLEWARE 裡注冊自定義的中間件類:

自定義中間件類的方法有:process_request 和 process_response。

Django(14):Django 中間件

process_request 方法有一個參數 request,這個 request 和視圖函數中的 request 是一樣的。

process_request 方法的傳回值可以是 None 也可以是 HttpResponse 對象。

傳回值是 None 的話,按正常流程繼續走,交給下一個中間件處理。

傳回值是 HttpResponse 對象,Django 将不執行後續視圖函數之前執行的方法以及視圖函數,直接以該中間件為起點,倒序執行中間件,且執行的是視圖函數之後執行的方法。

process_request 方法是在視圖函數之前執行的。

當配置多個中間件時,會按照 MIDDLEWARE中 的注冊順序,也就是清單的索引值,順序執行。

不同中間件之間傳遞的 request 參數都是同一個請求對象。

Django(14):Django 中間件

process_response 方法有兩個參數,一個是 request,一個是 response,request 是請求對象,response 是視圖函數傳回的 HttpResponse 對象,該方法必須要有傳回值,且必須是response。

process_response 方法是在視圖函數之後執行的。

當配置多個中間件時,會按照 MIDDLEWARE 中的注冊順序,也就是清單的索引值,倒序執行。

從下圖看,正常的情況下按照綠色的路線進行執行,假設中間件1有傳回值,則按照紅色的路線走,直接執行該類下的 process_response 方法傳回,後面的其他中間件就不會執行。

Django(14):Django 中間件

process_view 方法格式如下:

process_view 方法有四個參數:

request 是 HttpRequest 對象。

view_func 是 Django 即将使用的視圖函數。

view_args 是将傳遞給視圖的位置參數的清單。

view_kwargs 是将傳遞給視圖的關鍵字參數的字典。

view_args 和 view_kwargs 都不包含第一個視圖參數(request)。

process_view 方法是在視圖函數之前,process_request 方法之後執行的。

傳回值可以是 None、view_func(request) 或 HttpResponse 對象。

c.傳回值是 view_func(request),Django 将不執行後續視圖函數之前執行的方法,提前執行視圖函數,然後再倒序執行視圖函數之後執行的方法。

當最後一個中間件的 process_request 到達路由關系映射之後,傳回到第一個中間件 process_view,然後依次往下,到達視圖函數。

Django(14):Django 中間件
Django(14):Django 中間件

process_exception 方法如下:

參數說明:

exception 是視圖函數異常産生的 Exception 對象。

process_exception 方法隻有在視圖函數中出現異常了才執行,按照 settings 的注冊倒序執行。

在視圖函數之後,在 process_response 方法之前執行。

process_exception 方法的傳回值可以是一個 None 也可以是一個 HttpResponse 對象。

傳回值是 None,頁面會報 500 狀态碼錯誤,視圖函數不會執行。

process_exception 方法倒序執行,然後再倒序執行 process_response 方法。

傳回值是 HttpResponse 對象,頁面不會報錯,傳回狀态碼為 200。

視圖函數不執行,該中間件後續的 process_exception 方法也不執行,直接從最後一個中間件的 process_response 方法倒序開始執行。

若是 process_view 方法傳回視圖函數,提前執行了視圖函數,且視圖函數報錯,則無論 process_exception 方法的傳回值是什麼,頁面都會報錯, 且視圖函數和 process_exception 方法都不執行。

直接從最後一個中間件的 process_response 方法開始倒序執行:

Django(14):Django 中間件