Django 中間件

中間件

中間件介紹

什麼是中間件?

在視圖函數執行以前和執行以後均可以作一些額外的操做,本質上爲一個自定義類,類中定義了幾個方法,Django框架會在請求的特定的時間去執行這些方法。html

在 settings.py 中的位置數據庫

複製代碼
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',
]
複製代碼

自定義中間件

中間件能夠定義五個方法django

  • process_request(self,request)
  • process_view(self, request, view_func, view_args, view_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

返回值能夠是None或一個HttpResponse對象,瀏覽器

若是是None,則繼續按照django定義的規則向後繼續執行,session

若是是HttpResponse對象,則直接將該對象返回給用戶。框架

自定義一箇中間件示例

複製代碼
from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1裏面的 process_request")

    def process_response(self, request, response):
        print("MD1裏面的 process_response")
        return response
複製代碼

process_request

參數:函數

  request: 這個request和視圖函數中的request是同樣的(HttpRequest對象)post

返回值:url

  None :按正常流程繼續走,交給下一個中間件處理,spa

  HttpResponse對象: Django將不執行視圖函數,而將相應對象返回給瀏覽器。

執行順序:

  視圖函數以前

  註冊順序執行

總結 :

  1. 中間件的process_request方法是在執行視圖函數以前執行的。
  2. 當配置多箇中間件時,會按照 MIDDLEWARE 中的註冊順序,從前到後依次執行
  3. 不一樣中間件之間傳遞的request都是同一個對象

process_response

參數:

  request : 這個request和視圖函數中的request是同樣的

  response: 視圖函數返回的HttpResponse對象。

返回值:

  HttpResponse對象

執行順序:

  視圖函數以後

  註冊順序倒序

總結 :

  process_response 方法是在視圖函數以後執行的,而且順序是MD1比MD2先執行。(此時settings.py中 MD2比MD1先註冊)

  多箇中間件中的process_response方法是按照MIDDLEWARE中的註冊順序倒序執行的,

process_view

process_view(self, request, view_func, view_args, view_kwargs)

參數:

  request:這個request和視圖函數中的request是同樣的 (HttpRequest對象)

  view_func : Django即將使用的視圖函數。 (它是實際的函數對象,而不是函數的名稱做爲字符串。)

  view_args: 傳遞給視圖的位置參數的列表.

  view_kwargs: 傳遞給視圖的關鍵字參數的字典。 view_args和view_kwargs都不包含第一個視圖參數(request)。

返回值

  None: Django將繼續處理這個請求,執行任何其餘中間件的process_view方法,而後在執行相應的視圖。

  HttpResponse對象: Django不會調用適當的視圖函數。 它將執行中間件的process_response方法並將應用到該HttpResponse並返回結果。

執行順序

  調用視圖函數以前調用 process_view 方法。

  process_request 以後 

  註冊順序正序 

process_exception

process_exception(self, request, exception)

參數:

  request : 這個request和視圖函數中的request是同樣的 (HttpRequest對象)

  exception: 視圖函數異常產生的Exception對象。

返回值:

  None: 交給下一個中間件的 process_exception方法 來處理異常。

  HttpResponse對象: 往下執行 process_response 方法,並返回給瀏覽器,不然將默認處理異常

執行順序:

  視圖函數中出現異常了才執行,即視圖函數以後執行

  process_response 方法執行前執行 

  註冊順序的倒序執行

process_template_response(用的比較少)

process_template_response(self, request, response)

參數:

  request : 這個request和視圖函數中的request是同樣的 (HttpRequest對象)

  response : TemplateResponse對象(由視圖函數或者中間件產生)

返回值:

  HttpResponse對象: 直接返回響應對象結果給瀏覽器,再也不執行後面的方法

執行順序

  視圖函數執行完成後當即執行

    前提條件:那就是視圖函數返回的對象有一個render()方法(或者代表該對象是一個TemplateResponse對象或等價方法)。

  process_response 以前  

  註冊順序倒敘

中間件的執行流程

請求到達中間件以後,先按照正序執行每一個註冊中間件的process_reques方法,

process_request方法返回的值是None,就依次執行,

若是返回的值是HttpResponse對象,再也不執行後面的process_request方法,而是執行當前對應中間件的process_response方法,將HttpResponse對象返回給瀏覽器。

如圖:

  執行過程當中,第3箇中間件返回了一個HttpResponse對象,

  那麼第4,5,6中間件的process_request和process_response方法都不執行,

  往下順序執行3,2,1中間件的process_response方法。

 

process_request方法都執行完後,匹配路由,找到要執行的視圖函數,

執行視圖函數前,先執行 process_view方法,

  process_view方法返回None,繼續按順序執行,全部process_view方法執行完後執行視圖函數。

  process_view方法返回HttpResponse對象(加入中間件3 的process_view方法返回了HttpResponse對象)

    則4,5,6的process_view以及視圖函數都不執行,直接從最後一箇中間件,也就是中間件6的process_response方法開始倒序執行。

 process_template_response和process_exception兩個方法的觸發是有條件的,執行順序也是倒序。

總結全部的執行流程以下:

 

中間件版登陸驗證 

中間件版的登陸驗證須要依靠session,因此數據庫中要有django_session表。

urls.py

  urls.py

views.py

  views.py

login.html

  login.html

middlewares.py

  登陸校驗中間件

在settings.py中註冊

  settings.py中註冊中間件

AuthMD中間件註冊後,全部的請求都要走AuthMD的process_request方法。

訪問的URL在白名單內或者session中有user用戶名,則不作阻攔走正常流程;

若是URL在黑名單中,則返回This is an illegal URL的字符串;

正常的URL可是須要登陸後訪問,讓瀏覽器跳轉到登陸頁面。

注:AuthMD中間件中須要session,因此AuthMD註冊的位置要在session中間的下方。

Django請求流程圖

相關文章
相關標籤/搜索