Django-中間件

一:Django中的中間件

1:什麼是中間件

中間件顧名思義,是介於request與response處理之間的一道處理過程,相對比較輕量級,而且在全局上改變django的輸入與輸出。由於改變的是全局,因此須要謹慎實用,用很差會影響到性能。django

一些全局性的東西咱們總不能在每一個視圖函數中加入吧,這個時候就能夠用中間件了,至於爲何須要中間件?這須要你查看Django的整個流程了,到底中間件在整個框架中扮演什麼樣的角色) 服務器

2:中間件在Django框架中的使用

(1)Django框架

 

 

 

 

 

 

 

 

 咱們能夠看到全部的請求以及迴應消息都須要通過中間件,所以中間件有什麼做用呢?其實就顯而易見了,咱們能夠把它看成總控開關。cookie

(2) Django默認的中間件(setting.py)

每個中間件都有具體的功能。session

這些中間件會依次執行
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', ]

(3)如何查看中間件源碼

如 框架

 django.contrib.sessions.middleware import SessionMiddleware

點擊進去能夠查看函數

class SessionMiddleware(MiddlewareMixin):

    def process_request(self, request):
         .............

    def process_response(self, request, response):

        ..............
        return response

 

(4)中間件中的方法

中間件中一共有四個方法:性能

process_request

process_view

process_exception

process_response

當用戶發起請求的時候會依次通過全部的的中間件,這個時候的請求時process_request,最後到達views的函數中,views函數處理後,在依次穿過中間件,這個時候是process_response,最後返回給請求者。 url

 

 

二:自定義一箇中間件(process_request、process_response)

 1:自定義中間件

咱們也能夠本身定義一箇中間件,咱們能夠本身寫一個類,可是必須繼承MiddlewareMixinspa

須要導入3d

from django.utils.deprecation import MiddlewareMixin

 

 setting.py

views.py

def index(request):

    print("view函數...")
    return HttpResponse("OK")

 

 Mymiddlewares.py

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

結果:

Md1請求
Md2請求
view函數...
Md2返回
Md1返回

 2:中間件的簡單控制---攔截&偷樑換柱

若是當請求到達請求2的時候直接不符合條件返回,即return HttpResponse("Md2中斷"),程序將把請求直接發給中間件2返回,而後依次返回到請求者,結果以下:

返回Md2中斷的頁面,後臺打印以下:

Md1請求
Md2請求
Md2返回
Md1返回

 

 

流程圖以下:

3:中間件的簡單控制---白名單-放行

class Md1(MiddlewareMixin):

    def process_request(self,request):
        print("Md1請求")
        #白名單
        if   request.path in ['/login']
             #若是訪問的路徑是/login/,那麼就放行(返回值是none)
             return None 
 
    def process_response(self,request,response):
        print("Md1返回")
        return response

 

 

三:自定義一箇中間件(process_request、process_view、process_response)

1:瞭解process_view

流程中process_view是在url和view視圖之間

process_view(self, request, callback, callback_args, callback_kwargs)

 

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

    """
 
    :param request: 請求對象
    :param view_func: 將要執行的視圖函數
    :param view_args:將要執行的函數的位置參數
    :param view_kwargs:將要執行的函數的關鍵字參數
    :return:
    """

 

2:process_view的應用

Mymiddlewares.py修改以下

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依次返回到達用戶。

process_view能夠用來調用視圖函數:

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):

        # return HttpResponse("hello")

        response=callback(request,*callback_args,**callback_kwargs)   #參數:callback是將要執行的視圖函數
        return response

 

結果以下:

Md1請求
Md2請求
view函數...
Md2返回
Md1返回

注意:process_view若是有返回值,會越過其餘的process_view以及視圖函數,可是全部的process_response都還會執行。

 

四:自定義一箇中間件(process_request、process_view、process_exception、process_response)

1:瞭解process_exception

顧名思義,這個方法是用來處理錯誤的。正常狀況下,這個方法是不會被執行的。只有出現問題時纔會執行

process_exception(self, request, exception)

2:正常狀況看流程--根本就不執行

示例修改以下:

 

class Md1(MiddlewareMixin):

    def process_request(self,request):
        print("Md1請求")

    def process_response(self,request,response):
        print("Md1返回")
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):

        print("md1 process_view...")

    def process_exception(self):
        print("md1 process_exception...")



class Md2(MiddlewareMixin):

    def process_request(self,request):
        print("Md2請求")

    def process_response(self,request,response):
        print("Md2返回")
        return response
    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("md2 process_view...")

    def process_exception(self):
        print("md1 process_exception...")

 

結果以下:

 

Md1請求
Md2請求
md1 process_view...
md2 process_view...
view函數...

Md2返回
Md1返回

 

 

2:異常狀況看流程--倒序執行

當views出現錯誤時:

 

 將md2的process_exception修改以下:

 def process_exception(self,request,exception):

        print("md2 process_exception...")
        return HttpResponse("error")
Md1請求
Md2請求
md1 process_view...
md2 process_view...
view函數...
md2 process_exception...
Md2返回
Md1返回

 

 

五:總結流程

process_request-------------->urlt-------------->process_viewt-------------->view-------------->process_exceptiont-------------->process_response

 

六:應用案例

一、作IP訪問頻率限制

某些IP訪問服務器的頻率太高,進行攔截,好比限制每分鐘不能超過20次。

二、URL訪問過濾

若是用戶訪問的是login視圖(放過)

若是訪問其餘視圖,須要檢測是否是有session認證,已經有了放行,沒有返回login,這樣就免得在多個視圖函數上寫裝飾器了!

 

七:中間件的應用

-權限

-用戶登陸驗證

-Django的csrf是如何實現的?

  在process_view方法中

    -檢查視圖是否被 @csrf_exempt  (免除csrf認證)

    -去請求體或cookie中獲取token

 

 

    

    

 

    CBV模式:

      

      

      或者這麼寫

      

相關文章
相關標籤/搜索