django中介軟體介紹

輝輝輝輝a發表於2021-02-19

在學習django中介軟體之前,先來認識一下django的生命週期,如下圖所示:

 

 

 

django生命週期瀏覽器傳送的請求會先經過wsgiref模組處理解析出request(請求資料)給到中介軟體,然後通過路由控制執行對應的檢視函式,從而和模板,db進行互動,互動完的資料再通過檢視函式返回給中介軟體,最後wsgiref模組將返回的資料封裝成http形式的資料給到瀏覽器並進行展示。

 

 

瞭解了django的生命週期後,我們就可以開始著手寫一個自己的中介軟體了,接下來認識幾個常用的中介軟體方法

 

1.process_request

單箇中介軟體

首先在app下建立一個py檔案,定義你的中介軟體類名

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse


class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):

        print('MiddlewareShow1')

然後將你的py檔案路徑寫入django主專案的settings的MIDDLEWARE中

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',
    'proxy_pro.middleware.MiddlewareShow'  # 此條是新加的 從該專案路徑開始寫
]

然後執行一個檢視函式即可,檢視控制檯列印

 

 

 此時自己建立的process_request方法就生效了

 

多箇中介軟體

此時在之前的py檔案中再新建一個類

class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')

然後將新建類的路徑也放在django主專案的settings的MIDDLEWARE中

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',
    'proxy_pro.middleware.MiddlewareShow',
    'proxy_pro.middleware.MiddlewareShowTwo'
]

執行檢視函式,檢視控制檯列印

 

此時定義的兩個中介軟體都生效了,執行順序是先1後2

 

 2.process_response

分別在剛才的類中新增response方法

 

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse


class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')

    def process_response(self, request, response):
        print('MiddlewareShow1 Response')
        return response


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')

    def process_response(self, request, response):
        print('MiddlewareShow2 Response')
        return response

執行檢視函式,檢視控制檯列印

 

此時可以看出請求先依次執行了中介軟體的Request,然後再去執行檢視函式,返回是先執行跟後面的中介軟體再依次往前

 

這時突然冒出一個想法,如果在request時直接返回了某個東西,還會繼續去執行後面的檢視函式嗎?那我們就來測試一下

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse


class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')
        return HttpResponse('request1時已返回')

    def process_response(self, request, response):
        print('MiddlewareShow1 Response')
        return response


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')


    def process_response(self, request, response):
        print('MiddlewareShow2 Response')
        return response

執行檢視函式,檢視控制檯

 

 此時可以看出當request中有返回時,直接不執行後面的內容了

 

3.process_view

分別在剛才的py檔案中新增view方法

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse


class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')

    def process_response(self, request, response):
        print('MiddlewareShow1 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow1 process_view')


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')


    def process_response(self, request, response):
        print('MiddlewareShow2 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow2 process_view')

執行檢視函式,檢視控制檯返回

 

 此時可以看出這個process_view方法會在執行完request後執行,執行完再去執行檢視函式

 

這時候就有疑問了,那這個有什麼用呢?我們先把它裡面的引數列印一下

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse


class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')

    def process_response(self, request, response):
        print('MiddlewareShow1 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow1 process_view')
        print('=====>callback', callback)
        print('=====>callback_args', callback_args)


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')


    def process_response(self, request, response):
        print('MiddlewareShow2 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow2 process_view')

執行檢視函式列印結果

 

此時可以看到這個view裡面的引數callback是檢視方法,callback_args是請求引數,那我們試著去請求下看看

class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')

    def process_response(self, request, response):
        print('MiddlewareShow1 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow1 process_view')
        print('=====>callback', callback)
        print('=====>callback_args', callback_args)
        ret = callback(callback_args)  # 請求
        return ret


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')


    def process_response(self, request, response):
        print('MiddlewareShow2 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow2 process_view')

檢視列印結果

 

 結果顯然易見,請求檢視函式成功了,返回了以後就沒有去執行process_view2了,這邊的作用就是可以攔截請求

 

4.process_exception

分別在剛才的py檔案中新增exception方法

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse


class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')

    def process_response(self, request, response):
        print('MiddlewareShow1 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow1 process_view')
        # print('=====>callback', callback)
        # print('=====>callback_args', callback_args)
        # ret = callback(callback_args)
        # return ret
    
    def process_exception(self, request, exception):
        print('MiddlewareShow1 process_exception')
        return HttpResponse(exception)


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')


    def process_response(self, request, response):
        print('MiddlewareShow2 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow2 process_view')

    def process_exception(self, request, exception):
        print('MiddlewareShow2 process_exception')
        return HttpResponse(exception)

執行檢視函式,檢視控制檯

 

 問題來了,為啥沒有走這個中介軟體方法呢?別慌,我們在檢視函式中加個錯

def middle_show(request):
    leo
    
    print('執行了檢視函式')

    return HttpResponse('hhh')

 

此時在執行下看看

 

 此時可以看到當process_exception2獲取到報錯後,就返回了沒有執行process_exception1

那如果我們在process_exception1處理呢,我們來測試下

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse


class MiddlewareShow(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow1 Request')

    def process_response(self, request, response):
        print('MiddlewareShow1 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow1 process_view')
        # print('=====>callback', callback)
        # print('=====>callback_args', callback_args)
        # ret = callback(callback_args)
        # return ret

    def process_exception(self, request, exception):
        print('MiddlewareShow1 process_exception')
        return HttpResponse(exception)


class MiddlewareShowTwo(MiddlewareMixin):

    def process_request(self, request):
        print('MiddlewareShow2 Request')


    def process_response(self, request, response):
        print('MiddlewareShow2 Response')
        return response

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('MiddlewareShow2 process_view')

    def process_exception(self, request, exception):
        print('MiddlewareShow2 process_exception')

執行檢視函式,列印看下

 

 此時還會走到process_exception1哦,然後把錯誤返回給頁面。

 

 

以上就是django中介軟體的介紹,希望和大家多多學習!轉載請說明出處,尊重勞動成果!!!

 

相關文章