Django中間件


中間件是 Django 用來處理請求和響應的鈎子框架。它是一個輕量級的、底層級的“插件”系統,用於全局性地控制Django 的輸入或輸出,可以理解為一些關卡。
中間件可以放在你的工程的任何地方,並以Python路徑的方式進行訪問。
可以把中間件比喻成洋蔥,每一層代表一個中間件,每個請求從進入django到響應返回,django都可以通過中間件進行一定的操作。

啟用中間件

在settings.py中,MIDDLEWARE列表表示要啟用的中間件。


MIDDLEWARE = [
    # 安全中間件
    'django.middleware.security.SecurityMiddleware',
    # 會話中間件,啟用時支持session
    'django.contrib.sessions.middleware.SessionMiddleware',
    # “通用”中間件
    'django.middleware.common.CommonMiddleware',
    # CSRF 保護中間件
    'django.middleware.csrf.CsrfViewMiddleware',
    # 驗證中間件
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # 消息中間件
    'django.contrib.messages.middleware.MessageMiddleware',
    # X-Frame-Options 中間件
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

上面的是默認的配置,關於這些中間件的功能,可以點擊這里查看。

自定義中間件

自定義中間件有兩種方法,一種是比較老的方法,另一種是在老方法的基礎上的新的定義方式。

  • 老方式
    要點:
  1. 自定義一個from django.utils.deprecation.MiddlewareMixin的子類
  2. 為類寫鈎子函數(鈎子函數如下表)
鈎子函數 執行時機 執行順序(相對與配置列表) 參數 返回值
process_request 請求剛到來,執行視圖之前 正序 HttpRequest對象 None或者HttpResponse對象
process_response 視圖執行完畢,返回響應時 逆序 HttpRequest對象和HttpResponse對象 HttpResponse對象
process_view process_request之后,路由轉發到視圖,執行視圖之前 正序 HttpRequest對象, 視圖函數, view args參數, view kwargs參數 None或者HttpResponse對象
process_exception 視圖執行中發生異常時 逆序 HttpRequest對象和異常類對象 None或者HttpResponse對象
process_template_response 視圖剛執行完畢,process_response之前 逆序 HttpRequest對象和TemplateResponse對象 實現了render方法的響應對象

各個鈎子函數的執行順序

例子:

# app01/middlewares/miMiddleware.py

from django.utils.deprecation import MiddlewareMixin


class MyMiddleWare(MiddlewareMixin):

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

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

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("在執行%s視圖前" % view_func.__name__)

    def process_exception(self, request, exception):
        print("處理視圖異常...")

# settings.py

MIDDLEWARE = [
    "app01.middlewares.myMiddleware.MyMiddleWare",
]
  • 新方式
    不需要繼承MiddlewareMixin類,而且process_requestprocess_response定義__call__方法中。
class MyMiddleWare:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):

        print("處理請求")

        response = self.get_response(request)

        print("返回響應")

        return response

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

        print("在執行%s視圖前" %view_func.__name__)

    def process_exception(self,request,exception):
        print("處理視圖異常...")
		

同樣需要在settings配置MIDDLEWARE。

應用實例一:IP攔截
如果我們想限制某些IP對服務器的訪問,可以在settings.py中添加一個BLACKLIST(全大寫)列表,將被限制的IP地址寫入其中。
然后,我們就可以編寫下面的中間件了:

from django.http import HttpResponseForbidden
from django.conf import settings

class BlackListMiddleware():

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):

        if request.META['REMOTE_ADDR'] in getattr(settings, "BLACKLIST", []):
            return HttpResponseForbidden('<h1>該IP地址被限制訪問!</h1>')

        response = self.get_response(request)

        return response

應用實例二:DEBUG頁面
網站上線正式運行后,我們會將DEBUG改為 False,這樣更安全。但是發生服務器5xx系列錯誤時,管理員卻不能看到錯誤詳情,調試很不方便。有沒有辦法比較方便地解決這個問題呢?
即:

  • 普通訪問者看到的是500錯誤頁面
  • 管理員看到的是錯誤詳情Debug頁面

利用中間件就可以做到!代碼如下:

import sys
from django.views.debug import technical_500_response
from django.conf import settings


class DebugMiddleware():

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):

        response = self.get_response(request)

        return response

    def process_exception(self, request, exception):
        # 如果是管理員,則返回一個特殊的響應對象,也就是Debug頁面
        # 如果是普通用戶,則返回None,交給默認的流程處理
        if request.user.is_superuser or request.META.get('REMOTE_ADDR') in settings.ADMIN_IP:
            return technical_500_response(request, *sys.exc_info())


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM