您好,登錄后才能下訂單哦!
小編給大家分享一下Django中間件的使用方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
中間件是 Django 用來處理請求和響應的鉤子框架。它是一個輕量級的、底層級的“插件”系統,用于全局性地控制Django 的輸入或輸出,可以理解為內置的app或者小框架。
在django.core.handlers.base模塊中定義了如何接入中間件,這也是學習Django源碼的入口之一。
每個中間件組件負責實現一些特定的功能。例如,Django 包含一個中間件組件 AuthenticationMiddleware,它使用會話機制將用戶與請求request關聯起來。
中間件可以放在你的工程的任何地方,并以Python路徑的方式進行訪問。
Django 具有一些內置的中間件,并自動開啟了其中的一部分,我們可以根據自己的需要進行調整。
一、如何啟用中間件
若要啟用中間件組件,請將其添加到 Django 配置文件settings.py的 MIDDLEWARE 配置項列表中。
在 MIDDLEWARE 中,中間件由字符串表示。這個字符串以圓點分隔,指向中間件工廠的類或函數名的完整 Python 路徑。下面是使用 django-admin startproject命令創建工程后,默認的中間件配置:
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。而筆者的建議是保持默認的配置,這有助于你提高網站的安全性。
二、 中間件最關鍵的順序問題
MIDDLEWARE 的順序很重要,具有先后關系,因為有些中間件會依賴其他中間件。例如: AuthenticationMiddleware 需要在會話中間件中存儲的經過身份驗證的用戶信息,因此它必須在 SessionMiddleware 后面運行 。
在請求階段,調用視圖之前,Django 按照定義的順序執行中間件 MIDDLEWARE,自頂向下。
你可以把它想象成一個洋蔥:每個中間件類都是一個“皮層”,它包裹起了洋蔥的核心--實際業務視圖。如果請求通過了洋蔥的所有中間件層,一直到內核的視圖,那么響應將在返回的過程中以相反的順序再通過每個中間件層,最終返回給用戶。
如果某個層的執行過程認為當前的請求應該被拒絕,或者發生了某些錯誤,導致短路,直接返回了一個響應,那么剩下的中間件以及核心的視圖函數都不會被執行。
三、Django內置的中間件
Django內置了下面這些中間件,滿足了我們一般的需求:
Cache
緩存中間件
如果啟用了該中間件,Django會以CACHE_MIDDLEWARE_SECONDS 配置的參數進行全站級別的緩存。
Common
通用中間件
該中間件為我們提供了一些便利的功能:
禁止DISALLOWED_USER_AGENTS中的用戶代理訪問服務器
自動為URL添加斜杠后綴和www前綴功能。如果配置項 APPEND_SLASH 為True ,并且訪問的URL 沒有斜杠后綴,在URLconf中沒有匹配成功,將自動添加斜杠,然后再次匹配,如果匹配成功,就跳轉到對應的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中間件的使用方法”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。