Django(36)Django中間件詳解

什麼是Django中間件

  中間件(Middleware)是一個用來處理Django的請求(Request)和響應(Response)的框架級別的鉤子,它是一個輕量、低級別的插件系統,用於在全局範圍內改變Django的輸入和輸出。
 
  當用戶在網站中進行某個操做時,這個過程是用戶向網站發送HTTP請求(Request);而網站會根據用戶的操做發返回相關的網頁內容,這個過程稱爲響應處理(Response)。從請求到響應的過程當中,當Django接收到用戶請求時,首先通過中間件處理請求信息,執行相關的處理,而後將處理結果返回給用戶。

  從上圖中可清晰的看到,中間件的做用是處理用戶請求信息和返回響應內容。開發者能夠根據本身的開發需求自定義中間件,只要將自定義的中間件添加到配置屬性MIDDLEWARE中便可激活,通常狀況下,Django默認的中間件配置都可知足大部分開發需求
 前端

中間件的定義過程

  中間件在settings.py的配置屬性MIDDLEWARE中進行配置,在建立項目是,Django已默認配置了7箇中間件,每一箇中間件的說明以下:django

  • SecurityMiddleware:內置的安全機制,保護用戶與網站的通訊安全
  • SessionMiddleware:會話Session功能
  • CommonMiddleware:處理請求信息,規範化請求內容
  • CsrfViewMiddleware:開啓CSRF防禦功能
  • AuthenticationMiddleware:開啓內置的用戶認證系統
  • MessageMiddleware:開啓內置的信息提示功能
  • XFameOptionsMiddleware:防止惡意程序電腦及劫持

  爲了深刻了解中間件的定義過程,咱們在Pycharm裏打開並查看某個中間件的源碼文件,分析中間件的定義過程,以中間件SessionMiddleware爲例,源碼以下:瀏覽器

class SessionMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response
        engine = import_module(settings.SESSION_ENGINE)
        self.SessionStore = engine.SessionStore

  中間件SessionMiddleware繼承父類MiddlewareMixin,父類MiddlewareMixin只定義函數__init__和__call__,而中間件SessionMiddleware除了重寫父類的__init__以外,還定義了鉤子函數process_request和process_response。
 
  一個完整的中間件設有5個鉤子函數,Django將用戶請求到網站響應的過程進行階段劃分,每一個階段對應執行某個鉤子函數,每一個鉤子函數的運行說明以下。緩存

  • process_request():完成請求對象的建立,但用戶訪問的網址還沒有與網站的路由地址匹配。
  • process_view():完成用戶訪問的網址與路由地址的匹配,但還沒有執行視圖函數。
  • process_exception():在執行視圖函數的期間發生異常,好比代碼異常,主動拋出404異常等。
  • process_response():完成視圖函數的執行,但還沒有將響應內容返回瀏覽器
  • process_template_response():默認不執行,在視圖函數完成操做後調用,除非視圖函數返回的response中有render方法(幾乎不會用,能夠忽略)

 

實戰案例

  先來作準備工做,新建一個項目middleware_demo,建立一個子應用middleware_app並在settings.py中註冊,首先配置好路由地址,代碼以下安全

# middleware_demo.urls.py
urlpatterns = [
    path('middleware/', include('middleware_app.urls')),
]

# middleware_app.urls.py
urlpatterns = [
    path('', views.index, name="index")
]

路由配置完成後,建立視圖函數index,代碼以下:網絡

def index(request):
    print("中間件首頁")
    return HttpResponse('中間件首頁')

準備工做作完後,咱們在middleware_app應用中建立middlewares.py文件,填寫以下代碼:session

class FirstMiddleware(MiddlewareMixin):
    def process_request(self, request):
        """
        生成請求對象,路由匹配以前
        :param request:
        :return:
            若是返回response: 調用當前中間件的process_response處理
            若是返回None:調用下一個中間件的process_request處理
        """
        print("firstMiddleware request")

    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        路由匹配完成,視圖函數調用以前
        :param request:
        :param view_func: url路由匹配到的視圖函數
        :param view_args: 視圖函數的可變參數
        :param view_kwargs: 視圖函數的可變關鍵字參數
        :return:
            若是返回response:調用最後一箇中間件的process_response開始處理
            若是返回None:調用下一個中間件的process_view處理
        """
        """"""
        print("firstMiddleware process view")

    def process_exception(self, request, exception):
        """
        視圖函數發生異常時
        :param request:
        :param exception: 處理過程當中拋出的異常對象
        :return:
            若是返回response:以後的process_exception都不會觸發,而是直接調用最後一箇中間件的process_response處理
            若是返回None:調用上一個中間件的process_exception處理
        """
        print("firstMiddleware process exception")

    def process_response(self, request, response):
        """
        視圖函數執行後,響應內容返回瀏覽器以前
        :param request:
        :param response:
        :return:
            response:調用上一個中間件的process_response處理
        """
        print("firstMiddleware process response")
        return response

而後將自定義的中間件插入到settings.py的中間件列表中以下:app

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',
    'middleware_app.middlewares.FirstMiddleware',
]

由於中間件是有前後順序的,因此咱們通常自定義的都放在列表最後
 框架

接下來咱們訪問路由127.0.0.1/middleware/,查看Pycharm控制檯的日誌輸出ide

firstMiddleware request
firstMiddleware process view
中間件首頁
firstMiddleware process response

咱們能夠很清楚的看到請求的執行順序,下面咱們來總結一下

  • 1.用戶發送請求
  • 2.執行process_request
  • 3.urlconf路由匹配,找到對應的視圖函數
  • 4.執行視圖預處理方法process_view
  • 5.視圖函數
  • 6.process_template_response(若是視圖函數返回的response,有render方法,沒有則這一步不會執行)
  • 7.執行process_response
  • 8.返回response到用戶

  其中,在視圖函數和process_template_response處理過程當中,若是出現 exception ,那麼就會倒序執行中間件的process_exception
 

常見自定義中間件功能

  總之,你若是有對全局request或response的操做需求,那麼就可使用中間件,例如:

  1. IP過濾:對一些特定IP地址返回特定響應
  2. URL過濾:若是用戶訪問的是login視圖,則經過;若是訪問其餘視圖,須要檢測是否是有session已經有了就經過,沒有就返回login頁面。這樣就不用在多個視圖函數上寫裝飾器login_required
  3. 內容壓縮:response內容實現gzip的壓縮,返回壓縮後的內容給前端
  4. CDN:內容分發網絡,實現緩存,若是緩存中有數據直接返回,沒有找到緩存再去請求視圖
  5. URL過濾:某個子應用升級暫停使用,某個特定的path路徑下的請求,返回一個特定頁面
相關文章
相關標籤/搜索