在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 中間件
點(diǎn)擊劫持保護(hù)
安全問題歸檔
Model 類參考
將遺留數(shù)據(jù)庫整合到Django
關(guān)聯(lián)對象參考
內(nèi)建基于類的視圖的API
聚合
Django 中的用戶認(rèn)證
django.contrib.humanize
Django管理文檔生成器
分頁
使用Django輸出CSV
加密簽名
文件儲存API
安全
Django中的測試
國際化和本地化
為Django編寫首個補(bǔ)丁
條件表達(dá)式
日志
模型元選項(xiàng)
部署靜態(tài)文件
執(zhí)行查詢
使用Django認(rèn)證系統(tǒng)
基于類的視圖
中間件
編寫自定義的django-admin命令
Django 的設(shè)置
格式本地化
數(shù)據(jù)庫訪問優(yōu)化
錯誤報(bào)告
基于類的內(nèi)建通用視圖
編寫自定義存儲系統(tǒng)
編寫你的第一個 Django 程序 第3部分
編寫數(shù)據(jù)庫遷移
使用表單
編寫你的第一個 Django 程序 第2部分
編寫你的第一個 Django 程序 第1部分
如何使用會話
系統(tǒng)檢查框架
新手入門
信號
編寫視圖
如何使用WSGI 部署
編寫你的第一個Django應(yīng)用,第6部分
常見的網(wǎng)站應(yīng)用工具
Widgets
內(nèi)建的視圖
模型實(shí)例參考
視圖層
Django中的密碼管理
高級教程:如何編寫可重用的應(yīng)用
國際化和本地化
"本地特色"附加功能
TemplateResponse 和 SimpleTemplateResponse
模式編輯器
文件上傳
快速安裝指南
部署 Django
表單 API
表單素材 ( <code>Media</code> 類)
管理文件
其它核心功能
查找 API 參考
表單
Admin
數(shù)據(jù)庫函數(shù)
自定義查找
使用基于類的視圖處理表單
管理操作
開發(fā)過程
編寫你的第一個Django應(yīng)用,第5部分
進(jìn)行原始的sql查詢
模型層
多數(shù)據(jù)庫
編寫你的第一個 Django 程序 第4部分
Django安全
Django 初探
Django異常
重定向應(yīng)用
按需內(nèi)容處理
管理器
視圖裝飾器
驗(yàn)證器
使用Django輸出PDF
File對象
Django 的快捷函數(shù)
基于類的通用視圖 —— 索引
為模型提供初始數(shù)據(jù)
模板層
URL調(diào)度器
中間件
模型

中間件

中間件是一個介入Django的請求和響應(yīng)的處理過程中的鉤子框架。它是一個輕量級,底層的“插件”系統(tǒng),用于在全局修改Django的輸入或輸出。

中間件組件責(zé)任處理某些特殊的功能。例如,Django包含一個中間件組件,AuthenticationMiddleware ,使用會話將用戶和請求關(guān)聯(lián)。

這篇文檔講解了中間件如何工作,如何激活中間件,以及如何編寫自己的中間件。Django集成了一些內(nèi)置的中間件可以直接開箱即用。它們被歸檔在 內(nèi)置中間件參考.

激活中間件

要激活一個中間件組件,需要把它添加到你Django配置文件中的MIDDLEWARE_CLASSES 列表中。

在MIDDLEWARE_CLASSES中,每一個中間件組件用字符串的方式描述:一個完整的Python全路徑加上中間件的類名稱。例如,使用 django-admin startproject創(chuàng)建工程的時候生成的默認(rèn)值:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

Django的程序中,中間件不是必需的 — 只要你喜歡,MIDDLEWARE_CLASSES可以為空 — 但是強(qiáng)烈推薦你至少使用CommonMiddleware。

MIDDLEWARE_CLASSES中的順序非常重要,因?yàn)橐粋€中間件可能依賴于另外一個。例如,AuthenticationMiddleware在會話中儲存已認(rèn)證的用戶。所以它必須在SessionMiddleware之后運(yùn)行。一些關(guān)于Django中間件類的順序的常見提示,請見Middleware ordering。

鉤子和應(yīng)用順序

在請求階段中,調(diào)用視圖之前,Django會按照MIDDLEWARE_CLASSES中定義的順序自頂向下應(yīng)用中間件。會用到兩個鉤子:

  • process_request()
  • process_view()

在響應(yīng)階段中,調(diào)用視圖之后,中間件會按照相反的順序應(yīng)用,自底向上。會用到三個鉤子:

  • process_exception() (僅當(dāng)視圖拋出異常的時候)
  • process_template_response() (僅用于模板響應(yīng))
  • process_response()

如果你愿意的話,你可以把它想象成一顆洋蔥:每個中間件都是包裹視圖的一層“皮”。

每個鉤子的行為接下來會描述。

編寫自己的中間件

編寫自己的中間件很容易的。每個中間件組件是一個單獨(dú)的Python的class,你可以定一個或多個下面的這些方法:

process_request

process_request(request)

request是一個HttpRequest 對象。

在Django決定執(zhí)行哪個視圖(view)之前,process_request()會被每次請求調(diào)用。

它應(yīng)該返回一個None 或一個HttpResponse對象。如果返回 None, Django會繼續(xù)處理這個請求,執(zhí)行其他process_request()中間件,然后process_view()中間件顯示對應(yīng)的視圖。如果它返回一個HttpResponse對象,Django便不再會去調(diào)用其他的請求(request), 視圖(view)或其他中間件,或?qū)?yīng)的視圖;處理HttpResponse的中間件會處理任何返回的響應(yīng)(response)。

process_view

process_view(request, view_func, view_args, view_kwargs)

request是一個HttpRequest對象。view_func是 Django會調(diào)用的一個Python的函數(shù)。(它確實(shí)是一個函數(shù)對象,不是函數(shù)的字符名稱。) view_args是一個會被傳遞到視圖的位置參數(shù)列表,而view_kwargs 是一個會被傳遞到視圖的關(guān)鍵字參數(shù)字典。 view_args和 view_kwargs 都不包括第一個視圖參數(shù)(request)。

process_view()會在Django調(diào)用視圖(view)之前被調(diào)用。

它將返回None 或一個HttpResponse 對象。如果返回 None,將會繼續(xù)處理這個請求,執(zhí)行其他的process_view() 中間件,然后顯示對應(yīng)的視圖。如果返回HttpResponse對象,Django就不再會去調(diào)用其他的視圖(view),異常中間件(exception middleware)或?qū)?yīng)的視圖 ;它會把響應(yīng)中間件應(yīng)用到HttpResponse上,并返回結(jié)果。

注意

在中間件內(nèi)部,從process_request或者process_view方法中訪問request.POST或者request.REQUEST將會阻礙該中間 件之后的所有視圖無法修改request的上傳處理程序, 一般情況要避免這樣使用。

類CsrfViewMiddleware可以被認(rèn)為是個例外 ,因?yàn)樗峁┝薱srf_exempt() 和 csrf_protect()兩個允許視圖來精確控制 在哪個點(diǎn)需要開啟CSRF驗(yàn)證。

process_template_response

process_template_response(request, response)

request是一個HttpRequest對象。response是一個TemplateResponse對象(或等價的對象),由Django視圖或者中間件返回。

如果響應(yīng)的實(shí)例有render()方法,process_template_response()在視圖剛好執(zhí)行完畢之后被調(diào)用,這表明了它是一個TemplateResponse對象(或等價的對象)。

這個方法必須返回一個實(shí)現(xiàn)了render方法的響應(yīng)對象。它可以修改給定的response對象,通過修改 response.template_name和response.context_data或者它可以創(chuàng)建一個全新的 TemplateResponse或等價的對象。

你不需要顯式渲染響應(yīng) —— 一旦所有的模板響應(yīng)中間件被調(diào)用,響應(yīng)會自動被渲染。

在一個響應(yīng)的處理期間,中間件以相反的順序運(yùn)行,這包括process_template_response()。

process_response

process_response(request, response)

request是一個HttpRequest對象。response是Django視圖或者中間件返回的HttpResponse或者StreamingHttpResponse對象。

process_response()在所有響應(yīng)返回瀏覽器之前被調(diào)用。

這個方法必須返回HttpResponse或者StreamingHttpResponse對象。它可以改變已有的response,或者創(chuàng)建并返回新的HttpResponse或StreamingHttpResponse對象。

不像 process_request()和process_view()方法,即使同一個中間件類中的process_request()和process_view()方法會因?yàn)榍懊娴囊粋€中間件返回HttpResponse而被跳過,process_response()方法總是會被調(diào)用。特別是,這意味著你的process_response()方法不能依賴于process_request()方法中的設(shè)置。

最后,記住在響應(yīng)階段中,中間件以相反的順序被應(yīng)用,自底向上。意思是定義在MIDDLEWARE_CLASSES最底下的類會最先被運(yùn)行。

處理流式響應(yīng)

不像HttpResponse,StreamingHttpResponse并沒有content屬性。所以,中間件再也不能假設(shè)所有響應(yīng)都帶有content屬性。如果它們需要訪問內(nèi)容,他們必須測試是否為流式響應(yīng),并相應(yīng)地調(diào)整自己的行為。

if response.streaming:
    response.streaming_content = wrap_streaming_content(response.streaming_content)
else:
    response.content = alter_content(response.content)

注意

我們需要假設(shè)streaming_content可能會大到在內(nèi)存中無法容納。響應(yīng)中間件可能會把它封裝在新的生成器中,但是一定不要銷毀它。封裝一般會實(shí)現(xiàn)成這樣:

def wrap_streaming_content(content):
for chunk in content:
yield alter_content(chunk)

process_exception

process_exception(request, exception)

request是一個HttpRequest對象。exception是一個被視圖中的方法拋出來的 Exception對象。

當(dāng)一個視圖拋出異常時,Django會調(diào)用process_exception()來處理。process_exception()應(yīng)該返回一個None 或者一個HttpResponse對象。如果它返回一個HttpResponse對象,模型響應(yīng)和響應(yīng)中間件會被應(yīng)用,響應(yīng)結(jié)果會返回給瀏覽器。Otherwise, default exception handling kicks in.

再次提醒,在處理響應(yīng)期間,中間件的執(zhí)行順序是倒序執(zhí)行的,這包括process_exception。如果一個異常處理的中間件返回了一個響應(yīng),那這個中間件上面的中間件都將不會被調(diào)用。

__init__

大多數(shù)的中間件類都不需要一個初始化方法,因?yàn)橹虚g件的類定義僅僅是為process_*提供一個占位符。如果你確實(shí)需要一個全局的狀態(tài)那就可以通過__init__來加載。然后要銘記如下兩個警告:

Django初始化你的中間件無需任何參數(shù),因此不要定義一個有參數(shù)的__init__方法。 不像process_*每次請求到達(dá)都要調(diào)用__init__只會被調(diào)用一次,就是在Web服務(wù)啟動的時候。

標(biāo)記中間件不被使用

有時在運(yùn)行時決定是否一個中間件需要被加載是很有用的。 在這種情況下,你的中間件中的 __init__方法可以拋出一個django.core.exceptions.MiddlewareNotUsed異常。Django會從中間件處理過程中移除這部分中間件,并且當(dāng)DEBUG為True的時候在django.request記錄器中記錄調(diào)試信息。

1.8中的修改:

之前 MiddlewareNotUsed異常不會被記錄。

指導(dǎo)準(zhǔn)則

  • 中間件的類不能是任何類的子類。
  • 中間件可以存在與你Python路徑中的任何位置。 Django所關(guān)心的只是被包含在MIDDLEWARE_CLASSES中的配置。
  • 將Django’s available middleware作為例子隨便看看。
  • 如果你認(rèn)為你寫的中間件組建可能會對其他人有用,那就把它共享到社區(qū)! 讓我們知道它,我們會考慮把它添加到Django中。
上一篇:編寫視圖下一篇:安全問題歸檔