一、什麼是中間件 請求和響應之間的一道屏障 作用:控制請求和響應 Django預設的中間件 :(在django項目的setting模塊中,有一個 MIDDLEWARE_CLASS變數,其中每一個元素就是一個中間件 ) 每一個中間件都有具體的功能 二 、自定義中間件 中間件主要有幾個方法: 中間件執行 ...
一、什麼是中間件
請求和響應之間的一道屏障
作用:控制請求和響應
Django預設的中間件 :(在django項目的setting模塊中,有一個 MIDDLEWARE_CLASS變數,其中每一個元素就是一個中間件 )
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', ]
每一個中間件都有具體的功能
二 、自定義中間件
中間件主要有幾個方法:
-from django.utils.deprecation import MiddlewareMixin 先導入 -定義一個類,隨意命名,繼承MiddlewareMixin class MyMiddleware1(MiddlewareMixin): def process_request(self, request): print('MyMiddleware---->1---->process_request') # 返回HttpRspons對象,直接返回,走自己的process_response # 返回None的時候,繼續往下走 # return HttpResponse('i am middle--1') return None def process_response(self, request, response): print('MyMiddleware--->1---->process_response') return response -使用:在setting中註冊,是有順序的, MIDDLEWARE = [ 'app01.mymiddelware.MyMiddleware1', ]
中間件執行順序:
process_request,從上往下執行,
如果return HttpResponse的對象,直接返回了;
如果return None,繼續往下走
中間件的方法:
process_request:請求來的時候,會響應它
process_response:響應回去的時候,會走它
process_view (瞭解): request, callback(視圖函數), callback_args(無名分組的參數), callback_kwargs(有名分組的參數)
三、process_request和process_response
當用戶發起請求的時候會依次經過所有的中間件,這個時候請求 procsee_request,最後到達 views的函數中,views函數處理後 ,在依次穿過中間件,這個時候是process_response,最後返回給請求者。
上述截圖中的中間件都是Django中的,我們也可以自己定義一個中間件,我們可以自己寫一個類,但是必須繼承MiddlewareMixin
第一步:導入
from` `django.utils.deprecation ``import` `MiddlewareMixin
第二步 :自定義中間件
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class Md1(MiddlewareMixin): def process_request(self,request): print("Md1請求") def process_response(self,request,response): print("Md1返回") return response class Md2(MiddlewareMixin): def process_request(self,request): print("Md2請求") #return HttpResponse("Md2中斷") def process_response(self,request,response): print("Md2返回") return response
第三步:在view中定義一個視圖函數
def index(request): print("view函數...") return HttpResponse("OK")
第四步:在setting.py的MIDDLEWARE里註冊自己定義的中間件
結果:
Md1請求
Md2請求
view函數...
Md2返回
Md1返回
註意:如果當請求到達請求2的時候 直接不符合條件返回,即return HttpResponse(‘MD2中斷’),程式將把請求直接發給中間件2返回,然後依次 返回到請求者,結果如下 :
返回Md2中斷 的頁面,後臺列印如下:
Md1請求
Md2請求
Md2返回
Md1返回
流程圖 如下 :
總結:
1、中間件的process_request方法是在執行視圖之前 執行的。
2、當前配置多個中間件時,會按照MIDDLEWARE中的註冊順序,也就是列表的索引值,從前到後一依次執行。
3、不同中間件之間傳遞的request都是同一個對象。
多個中間件中 的process_response的方法是按照MIDDLEWARE中的註冊順序倒序執行的,一個中間件中的process_request方法首先執行,而他的process_response方法最後執行 ,最後一個中間件的process_request方法最後一個執行,它的process_response方法是最先執行的。
process_view
process_view(self, request, view_func, view_args, view_kwargs)
該方法有四個參數
request是HttpRequest對象。
view_func是Django即將使用的視圖函數。 (它是實際的函數對象,而不是函數的名稱作為字元串。)
view_args是將傳遞給視圖的位置參數的列表.
view_kwargs是將傳遞給視圖的關鍵字參數的字典。 view_args和view_kwargs都不包含第一個視圖參數(request)。
Django會在調用視圖函數之前調用process_view方法。
它應該返回None或一個HttpResponse對象。 如果返回None,Django將繼續處理這個請求,執行任何其他中間件的process_view方法,然後在執行相應的視圖。 如果它返回一個HttpResponse對象,Django不會調用適當的視圖函數。 它將執行中間件的process_response方法並將應用到該HttpResponse並返回結果。
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class Md1(MiddlewareMixin): def process_request(self,request): print("Md1請求") #return HttpResponse("Md1中斷") def process_response(self,request,response): print("Md1返回") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("Md1view") class Md2(MiddlewareMixin): def process_request(self,request): print("Md2請求") return HttpResponse("Md2中斷") def process_response(self,request,response): print("Md2返回") return response def process_view(self, request, callback, callback_args, callback_kwargs): print("Md2view")
結果如下:
Md1請求
Md2請求
Md1view
Md2view
view函數...
Md2返回
Md1返回
下圖進行分析 上面的過程:
當最後一個中間的process_request到達路由關係映射之後,返回到中間件1的process_view,然後依次往下,到達views函數,最後通過process_response依次返回到達用戶。