django中間件介紹

在學習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中間件的介紹,希望和大家多多學習!轉載請說明出處,尊重勞動成果!!!