溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Django中間件的使用方法

發(fā)布時間:2020-11-24 13:53:48 來源:億速云 閱讀:223 作者:小新 欄目:編程語言

小編給大家分享一下Django中間件的使用方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

中間件是 Django 用來處理請求和響應的鉤子框架。它是一個輕量級的、底層級的“插件”系統(tǒng),用于全局性地控制Django 的輸入或輸出,可以理解為內(nèi)置的app或者小框架。

在django.core.handlers.base模塊中定義了如何接入中間件,這也是學習Django源碼的入口之一。

每個中間件組件負責實現(xiàn)一些特定的功能。例如,Django 包含一個中間件組件 AuthenticationMiddleware,它使用會話機制將用戶與請求request關聯(lián)起來。

中間件可以放在你的工程的任何地方,并以Python路徑的方式進行訪問。

Django 具有一些內(nèi)置的中間件,并自動開啟了其中的一部分,我們可以根據(jù)自己的需要進行調(diào)整。

一、如何啟用中間件

若要啟用中間件組件,請將其添加到 Django 配置文件settings.py的 MIDDLEWARE 配置項列表中。

在 MIDDLEWARE 中,中間件由字符串表示。這個字符串以圓點分隔,指向中間件工廠的類或函數(shù)名的完整 Python 路徑。下面是使用 django-admin startproject命令創(chuàng)建工程后,默認的中間件配置:

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',
]

實際上在Django中可以不使用任何中間件,如果你愿意的話,MIDDLEWARE 配置項可以為空。但是強烈建議至少使用 CommonMiddleware。而筆者的建議是保持默認的配置,這有助于你提高網(wǎng)站的安全性。

二、 中間件最關鍵的順序問題

MIDDLEWARE 的順序很重要,具有先后關系,因為有些中間件會依賴其他中間件。例如: AuthenticationMiddleware 需要在會話中間件中存儲的經(jīng)過身份驗證的用戶信息,因此它必須在 SessionMiddleware 后面運行 。

在請求階段,調(diào)用視圖之前,Django 按照定義的順序執(zhí)行中間件 MIDDLEWARE,自頂向下。

你可以把它想象成一個洋蔥:每個中間件類都是一個“皮層”,它包裹起了洋蔥的核心--實際業(yè)務視圖。如果請求通過了洋蔥的所有中間件層,一直到內(nèi)核的視圖,那么響應將在返回的過程中以相反的順序再通過每個中間件層,最終返回給用戶。

如果某個層的執(zhí)行過程認為當前的請求應該被拒絕,或者發(fā)生了某些錯誤,導致短路,直接返回了一個響應,那么剩下的中間件以及核心的視圖函數(shù)都不會被執(zhí)行。

三、Django內(nèi)置的中間件

Django內(nèi)置了下面這些中間件,滿足了我們一般的需求:

Cache

緩存中間件

如果啟用了該中間件,Django會以CACHE_MIDDLEWARE_SECONDS 配置的參數(shù)進行全站級別的緩存。

Common

通用中間件

該中間件為我們提供了一些便利的功能:

禁止DISALLOWED_USER_AGENTS中的用戶代理訪問服務器

自動為URL添加斜杠后綴和www前綴功能。如果配置項 APPEND_SLASH 為True ,并且訪問的URL 沒有斜杠后綴,在URLconf中沒有匹配成功,將自動添加斜杠,然后再次匹配,如果匹配成功,就跳轉(zhuǎn)到對應的url。 PREPEND_WWW 的功能類似。

為非流式響應設置Content-Length頭部信息。

作為展示的例子,這里額外貼出它的源代碼,位于django.middleware.common模塊中,比較簡單,很容易讀懂和理解:

class CommonMiddleware(MiddlewareMixin):
    """    去掉了doc    """
    response_redirect_class = HttpResponsePermanentRedirect

    def process_request(self, request):
        # Check for denied User-Agents
        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    raise PermissionDenied('Forbidden user agent')

        # Check for a redirect based on settings.PREPEND_WWW
        host = request.get_host()
        must_prepend = settings.PREPEND_WWW and host and not host.startswith('www.')
        redirect_url = ('%s://www.%s' % (request.scheme, host)) if must_prepend else ''

        # Check if a slash should be appended
        if self.should_redirect_with_slash(request):
            path = self.get_full_path_with_slash(request)
        else:
            path = request.get_full_path()

        # Return a redirect if necessary
        if redirect_url or path != request.get_full_path():
            redirect_url += path
            return self.response_redirect_class(redirect_url)

    def should_redirect_with_slash(self, request):

        if settings.APPEND_SLASH and not request.path_info.endswith('/'):
            urlconf = getattr(request, 'urlconf', None)
            return (
                not is_valid_path(request.path_info, urlconf) and
                is_valid_path('%s/' % request.path_info, urlconf)
            )
        return False

    def get_full_path_with_slash(self, request):

        new_path = request.get_full_path(force_append_slash=True)
        if settings.DEBUG and request.method in ('POST', 'PUT', 'PATCH'):
            raise RuntimeError(
                "You called this URL via %(method)s, but the URL doesn't end "
                "in a slash and you have APPEND_SLASH set. Django can't "
                "redirect to the slash URL while maintaining %(method)s data. "
                "Change your form to point to %(url)s (note the trailing "
                "slash), or set APPEND_SLASH=False in your Django settings." % {
                    'method': request.method,
                    'url': request.get_host() + new_path,
                }
            )
        return new_path

    def process_response(self, request, response):
        # If the given URL is "Not Found", then check if we should redirect to
        # a path with a slash appended.
        if response.status_code == 404:
            if self.should_redirect_with_slash(request):
                return self.response_redirect_class(self.get_full_path_with_slash(request))

        if settings.USE_ETAGS and self.needs_etag(response):
            warnings.warn(
                "The USE_ETAGS setting is deprecated in favor of "
                "ConditionalGetMiddleware which sets the ETag regardless of "
                "the setting. CommonMiddleware won't do ETag processing in "
                "Django 2.1.",
                RemovedInDjango21Warning
            )
            if not response.has_header('ETag'):
                set_response_etag(response)

            if response.has_header('ETag'):
                return get_conditional_response(
                    request,
                    etag=response['ETag'],
                    response=response,
                )
        # Add the Content-Length header to non-streaming responses if not
        # already set.
        if not response.streaming and not response.has_header('Content-Length'):
            response['Content-Length'] = str(len(response.content))

        return response

    def needs_etag(self, response):
        """Return True if an ETag header should be added to response."""
        cache_control_headers = cc_delim_re.split(response.get('Cache-Control', ''))
        return all(header.lower() != 'no-store' for header in cache_control_headers)

以上是“Django中間件的使用方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI