中間件
中間件介紹
什麼是中間件?
在視圖函數執行以前和執行以後均可以作一些額外的操做,本質上爲一個自定義類,類中定義了幾個方法,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將不執行視圖函數,而將相應對象返回給瀏覽器。
執行順序:
視圖函數以前
註冊順序執行
總結 :
- 中間件的process_request方法是在執行視圖函數以前執行的。
- 當配置多箇中間件時,會按照 MIDDLEWARE 中的註冊順序,從前到後依次執行
- 不一樣中間件之間傳遞的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
![](http://static.javashuo.com/static/loading.gif)
views.py
![](http://static.javashuo.com/static/loading.gif)
login.html
![](http://static.javashuo.com/static/loading.gif)
middlewares.py
![](http://static.javashuo.com/static/loading.gif)
在settings.py中註冊
![](http://static.javashuo.com/static/loading.gif)
AuthMD中間件註冊後,全部的請求都要走AuthMD的process_request方法。
訪問的URL在白名單內或者session中有user用戶名,則不作阻攔走正常流程;
若是URL在黑名單中,則返回This is an illegal URL的字符串;
正常的URL可是須要登陸後訪問,讓瀏覽器跳轉到登陸頁面。
注:AuthMD中間件中須要session,因此AuthMD註冊的位置要在session中間的下方。