目錄
一.介紹
1.什么是Django中間件
2.作用:
3.示例
二.Django請求生命周期流程圖
三.Django中間件是Django的門戶
四.中間件方法
1.必須掌握的中間件方法
(1)process_request:
示例:
2.需要了解的中間件方法
(1)process_view
示例:
(2)process_template_response
示例:
(3)process_exception
示例:
五.自定義中間件
1.process_request
1.路由層
2.視圖層
3.配置文件
4.自定義中間件
5.總結
(1)執行順序
(2)沒有定義process_request
(3)定義了返回值
(4)總結
2.process_response
3.小結
一.介紹
1.什么是Django中間件
- Django中間件是一個輕量級、可重用的組件,用于處理Django請求和響應的過程
- 它提供了對請求和響應進行全局處理的機制,可以在請求達到視圖之前進行預處理或在響應返回給客戶端之前進行后處理
- 中間件是按照順序依次執行的,每個中間件都可以對請求和響應進行修改、補充或處理
- 在Django的setting.py配置文件中,通過MIDDLEWARE設置來定義中間件的順序
2.作用:
- 認證和授權:
- 中間件可以在請求到達視圖之前進行用戶認證和權限驗證,確保只有經過授權的用戶才能訪問敏感資源
- 請求和響應處理
- 中間件可以在請求到達視圖之前對請求進行預處理
- 例如添加請求頭信息、檢查請求參數的合法性等造作
- 同時,在視圖函數返回響應給客戶端之前,中間件還可以對響應進行后處理
- 例如添加額外的響應頭、包裝響應數據等操作
- 中間件可以在請求到達視圖之前對請求進行預處理
- 異常處理:
- 中間件還可以捕獲視圖函數中可能拋出的異常,并做相應的處理
- 例如記錄異常日志、返回自定義錯誤信息等
- 中間件還可以捕獲視圖函數中可能拋出的異常,并做相應的處理
- 性能優化:
- 通過中間件可以對請求進行性能檢測,緩存處理、壓縮響應等操作,提升網站的整體性能
3.示例
class MyMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 在視圖函數調用之前的預處理邏輯# ...response = self.get_response(request)# 在響應返回給客戶端之前的后處理邏輯# ...return response
二.Django請求生命周期流程圖
- 客戶端發出HTTP請求
- 請求被Web服務器接收并傳遞給Django應用程序
- Django中的WSGI中間件開始處理請求,并可進行一些預處理操作
- 中間件將請求傳遞給URL分發器(URL Dispatcher)
- URL分發器根據URL模式將請求路由到相應的視圖函數或處理器(View/Handler)
- 視圖函數或處理器執行相應的業務邏輯,可能會與數據庫等外部資源交互
- 視圖函數或處理器返回一個HTTP響應對象
- 響應對象經過中間件,可以在此進行后處理操作
- 響應被發送給Web服務器
- Web服務器將響應發送回客戶端
三.Django中間件是Django的門戶
- 請求發來的時候需要先經過中間件才能到達真正的Django后端
- 響應返回的時候,最后也需要進過中間件返回發送出去
四.中間件方法
Django支持程序員自定義中間件并且給程序員5個中間件
1.必須掌握的中間件方法
(1)process_request:
- 執行順序
? ? ? ? 請求來的時候需要經過每一個中間件的process_request方法
? ? ? ? 結果的順序是按照配置文件中注冊的中間件從上往下的順序執行的- 沒有定義process_request
? ? ? ? 如果沒有定義這個方法就跳過這個中間件- 定義了返回值
? ? ? ? 如果在自定義中間件中定義了返回值(三板斧),那么請求將不再繼續執行,而是直接原路返回(校驗失敗不允許訪問)- 總結
? ? ? ? process_request方法就是用來做全局相關的所有限制功能
- 該方法在每個請求到達視圖之前被調用,可以對請求進行預處理
- 例如,進行身份驗證,訪問控制或請求日志記錄等操作
- 它接收一個HttpRequest對象和HttpResponse對象作為參數,并且必須返回一個HttpResponse對象
示例:
class CustomResponseMiddleware:def process_response(self, request, response):# 在這里對響應進行處理response['X-Custom-Header'] = 'Custom Value'return response
2.需要了解的中間件方法
(1)process_view
- 路由匹配成功后執行視圖函數之前
- 會自動執行中間件里面的該方法
- 順序是按照配置文件中注冊的中間件從上而下的順序執行
- 該方法在請求到達視圖之前被調用,在視圖函數執行前執行。
- 可以在此處進行一些操作
- 如修改請求參數或進行記錄等。
- 它接收一個HttpRequest對象和一個視圖函數作為參數,并且可以返回一個HttpResponse對象或None。
示例:
class LoggingMiddleware:def process_view(self, request, view_func, view_args, view_kwargs):# 在這里記錄日志logger.info(f"Request received: {request.path}")# 返回None,繼續執行原視圖函數return None
(2)process_template_response
返回的 HttpResponse 對象有 render 屬性的時候才會觸發
- 順序是按照配置文件中注冊了的中間件從下往上依次經過
- 該方法在視圖函數返回一個TemplateResponse對象時調用。
- 可以在此處修改模板響應
- 例如添加全局的上下文數據或進行額外的渲染操作。
- 它接收一個HttpRequest對象和一個TemplateResponse對象作為參數,并且必須返回一個TemplateResponse對象。
示例:
class GlobalContextMiddleware:def process_template_response(self, request, response):# 在這里添加全局的上下文數據response.context_data['global_data'] = "Global Value"return response
(3)process_exception
- 當視圖函數中出現異常的情況下觸發
- 順序是按照配置文件中注冊了的中間件從下往上依次經過
- 該方法在視圖函數拋出異常時被調用。
- 可以在此處捕獲異常并進行處理
- 例如返回一個定制的錯誤頁面或進行日志記錄等。
- 它接收一個HttpRequest對象和一個異常對象作為參數,可以返回一個HttpResponse對象來替代原始的異常響應。
示例:
class ErrorHandlerMiddleware:def process_exception(self, request, exception):# 在這里處理異常if isinstance(exception, CustomException):# 如果自定義異常,返回一個定制的錯誤頁面return render(request, 'error.html', {'error': str(exception)})else:# 默認情況,返回一個500服務器錯誤return HttpResponseServerError("Internal Server Error")
五.自定義中間件
1.process_request
1.路由層
from app01 import viewsurlpatterns = [path('admin/', admin.site.urls),path('index/',views.index),
]
2.視圖層
def index(request):print("這是視圖函數index")return HttpResponse("index 的返回值")
3.配置文件
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',# 注冊自己的中間件(在應用下創建路徑會有提示,但是如果在項目下創建就沒有提示,需要自己根據路徑書寫)'app01.mymiddle.my_middle.MyMiddle',# 誰先注冊就先執行誰'app01.mymiddle.my_middle.MyMiddle2',
]
4.自定義中間件
# -*-coding: Utf-8 -*-
# @File : my_middle .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/7/17# 引入父類
from django.utils.deprecation import MiddlewareMixinclass MyMiddle(MiddlewareMixin):def process_request(self, request):print("這是第一個自定義中間件中的 process_request 方法")class MyMiddle2(MiddlewareMixin):def process_request(self, request):print("這是第二個自定義中間件中的 process_request 方法")
5.總結
(1)執行順序
- 請求來的時候需要經過每一個中間件的 process_request 方法
- 結果的順序是按照配置文件中注冊的中間件從上往下的順序執行的
(2)沒有定義process_request
- 如果沒有定義這個方法,就跳過這個中間件
(3)定義了返回值
- 如果在自定義中間件中定義了返回值(三板斧),那么請求將不再繼續執行,而是直接原路返回(校驗失敗不允許訪問)
(4)總結
- process_request 方法就是用來 做全局相關的所有限制功能
2.process_response
# 引入父類
from django.utils.deprecation import MiddlewareMixinclass MyMiddle(MiddlewareMixin):def process_request(self, request):print("這是第一個自定義中間件中的 process_request 方法")def process_response(self, request, response):''':param request: :param response: 就是Django返回給瀏覽器的內容:return: '''print("這是第一個自定義中間件中的 process_response 方法")# 必須返回 responserreturn response
-
響應被返回的時候需要結束每一個中間件里面的 process_response 方法
- 該方法有兩個額外的參數
- request
- response
- 該方法有兩個額外的參數
-
該方法必須返回 HttpResponse 對象
- 默認是response
- 支持自定義
-
順序是按照配置文件中注冊過的中間件從下往上依次經過
- 如果沒有定義,則跳過,校驗下一個
3.小結
-
如果在第一個 process_request 方法就已經返回了 HttpResponse 對象,那么響應被返回的時候是經過所有的中間件里面的 process_response 方法還是會發生其他?
- 會直接走同級別的 process_response 方法 ,然后直接返回
-
flask框架的中間件也有一個類似的方法
- 但是flask返回數據就必須經過所有中間件里面的 process_response 方法