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

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

按需內(nèi)容處理

HTTP客戶端可能發(fā)送一些協(xié)議頭來(lái)告訴服務(wù)端它們已經(jīng)看過(guò)了哪些資源。這在獲取網(wǎng)頁(yè)(使用HTTPGET請(qǐng)求)時(shí)非常常見(jiàn),可以避免發(fā)送客戶端已經(jīng)獲得的完整數(shù)據(jù)。然而,相同的協(xié)議頭可用于所有HTTP方法(POST, PUT, DELETE, 以及其它)。

對(duì)于每一個(gè)Django從視圖發(fā)回的頁(yè)面(響應(yīng)),都會(huì)提供兩個(gè)HTTP協(xié)議頭:ETagLast-Modified。這些協(xié)議頭在HTTP響應(yīng)中是可選的。它們可以由你的視圖函數(shù)設(shè)置,或者你可以依靠 CommonMiddleware 中間件來(lái)設(shè)置ETag 協(xié)議頭。

當(dāng)你的客戶端再次請(qǐng)求相同的資源時(shí),它可能會(huì)發(fā)送 If-modified-since 或者If-unmodified-since的協(xié)議頭,包含之前發(fā)送的最后修改時(shí)間;或者 If-matchIf-none-match協(xié)議頭,包含之前發(fā)送的ETag。如果頁(yè)面的當(dāng)前版本匹配客戶端發(fā)送的ETag,或者如果資源沒(méi)有被修改,會(huì)發(fā)回304狀態(tài)碼,而不是一個(gè)完整的回復(fù),告訴客戶端沒(méi)有任何修改。根據(jù)協(xié)議頭,如果頁(yè)面被修改了,或者不匹配客戶端發(fā)送的 ETag,會(huì)返回412(先決條件失敗,Precondition Failed)狀態(tài)碼。

當(dāng)你需要更多精細(xì)化的控制時(shí),你可以使用每個(gè)視圖的按需處理函數(shù)。

Changed in Django 1.8:

向按需視圖處理添加If-unmodified-since協(xié)議頭的支持

The condition

有時(shí)(實(shí)際上是經(jīng)常),你可以創(chuàng)建一些函數(shù)來(lái)快速計(jì)算出資源的ETag值或者最后修改時(shí)間,并不需要執(zhí)行構(gòu)建完整視圖所需的所有步驟。Django可以使用這些函數(shù)來(lái)為視圖處理提供一個(gè)“early bailout”的選項(xiàng)。來(lái)告訴客戶端,內(nèi)容自從上次請(qǐng)求并沒(méi)有任何改動(dòng)。

這兩個(gè)函數(shù)作為參數(shù)傳遞到django.views.decorators.http.condition裝飾器中。這個(gè)裝時(shí)期使用這兩個(gè)函數(shù)(如果你不能既快又容易得計(jì)算出來(lái),你只需要提供一個(gè))來(lái)弄清楚是否HTTP請(qǐng)求中的協(xié)議頭匹配那些資源。如果它們不匹配,會(huì)生成資源的一份新的副本,并調(diào)用你的普通視圖。

condition裝飾器的簽名為i:

condition(etag_func=None, last_modified_func=None)

計(jì)算ETag的最后修改時(shí)間的兩個(gè)函數(shù),會(huì)以相同的順序傳入request對(duì)象和相同的參數(shù),就像它們封裝的視圖函數(shù)那樣。last_modified_func函數(shù)應(yīng)該返回一個(gè)標(biāo)準(zhǔn)的datetime值,它制訂了資源修改的最后時(shí)間,或者資源不存在為 None。傳遞給etag裝飾器的函數(shù)應(yīng)該返回一個(gè)表示資源Etag的字符串,或者資源不存在時(shí)為None

用一個(gè)例子可以很好展示如何使用這一特性。假設(shè)你有這兩個(gè)模型,表示一個(gè)簡(jiǎn)單的博客系統(tǒng):

import datetime
from django.db import models

class Blog(models.Model):
    ...

class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    published = models.DateTimeField(default=datetime.datetime.now)
    ...

如果頭版展示最后的博客文章,僅僅在你添加新文章的時(shí)候修改,你可以非??焖俚赜?jì)算出最后修改時(shí)間。你需要這個(gè)博客每一篇文章的最后 發(fā)布 日期。實(shí)現(xiàn)它的一種方式是:

def latest_entry(request, blog_id):
    return Entry.objects.filter(blog=blog_id).latest("published").published

接下來(lái)你可以使用這個(gè)函數(shù),來(lái)為你的頭版視圖事先探測(cè)未修改的頁(yè)面:

from django.views.decorators.http import condition

@condition(last_modified_func=latest_entry)
def front_page(request, blog_id):
    ...

只計(jì)算一個(gè)值的快捷方式

一個(gè)普遍的原則是,如果你提供了計(jì)算 ETag_和_最后修改時(shí)間的函數(shù),你應(yīng)該這樣做:你并不知道HTTP客戶端會(huì)發(fā)給你哪個(gè)協(xié)議頭,所以要準(zhǔn)備好處理兩種情況。但是,有時(shí)只有二者之一容易計(jì)算,并且Django只提供給你計(jì)算ETag或最后修改日期的裝飾器。

django.views.decorators.http.etagdjango.views.decorators.http.last_modified作為condition裝飾器,傳入相同類(lèi)型的函數(shù)。他們的簽名是:

etag(etag_func)
last_modified(last_modified_func)

我們可以編寫(xiě)一個(gè)初期的示例,它僅僅使用最后修改日期的函數(shù),使用這些裝飾器之一:

@last_modified(latest_entry)
def front_page(request, blog_id):
    ...

...或者:

def front_page(request, blog_id):
    ...
front_page = last_modified(latest_entry)(front_page)

Use condition

如果你想要測(cè)試兩個(gè)先決條件,把etaglast_modified裝飾器鏈到一起看起來(lái)很不錯(cuò)。但是,這會(huì)導(dǎo)致不正確的行為:

# Bad code. Don't do this!
@etag(etag_func)
@last_modified(last_modified_func)
def my_view(request):
    # ...

# End of bad code.

第一個(gè)裝飾器不知道后面的任何事情,并且可能發(fā)送“未修改”的響應(yīng),即使第二個(gè)裝飾器會(huì)處理別的事情。condition裝飾器同時(shí)更使用兩個(gè)回調(diào)函數(shù),來(lái)弄清楚哪個(gè)是正確的行為。

使用帶有其它HTTP方法的裝飾器

condition裝飾器不僅僅對(duì)GETHEAD請(qǐng)求有用(HEAD請(qǐng)求在這種情況下和GET相同)。它也可以用于為 POST, PUTDELETE請(qǐng)求提供檢查。在這些情況下,不是要返回一個(gè)“未修改(not modified,314)”的響應(yīng),而是要告訴服務(wù)端,它們嘗試修改的資源在此期間被修改了。

例如,考慮以下客戶端和服務(wù)端之間的交互:

  1. 客戶端請(qǐng)求/foo/。
  2. 服務(wù)端回復(fù)一些帶有"abcd1234"ETag的內(nèi)容。
  3. 客戶端發(fā)送HTTP PUT 請(qǐng)求到 /foo/ 來(lái)更新資源。同時(shí)也發(fā)送了If-Match: "abcd1234" 協(xié)議頭來(lái)指定嘗試更新的版本。
  4. 服務(wù)端檢查是否資源已經(jīng)被修改,通過(guò)和GET 上所做的相同方式計(jì)算ETag(使用相同的函數(shù))。如果資源 已經(jīng) 修改了,會(huì)返回412狀態(tài)碼,意思是“先決條件失?。╬recondition failed)”。
  5. 客戶端在接收到412響應(yīng)之后,發(fā)送 GET請(qǐng)求到 /foo/,來(lái)在更新之前獲取內(nèi)容的新版本。

重要的事情是,這個(gè)例子展示了在所有情況下,ETag和最后修改時(shí)間值都采用相同函數(shù)計(jì)算。實(shí)際上,你 應(yīng)該 使用相同函數(shù),以便每次都返回相同的值。

使用中間件按需處理來(lái)比較

你可能注意到,Django已經(jīng)通過(guò)django.middleware.http.ConditionalGetMiddlewareCommonMiddleware.提供了簡(jiǎn)單和直接的GET 的按需處理。這些中間件易于使用并且適用于多種情況,然而它們的功能有一些高級(jí)用法上的限制:

  • 它們?cè)谌稚嫌糜谀沩?xiàng)目中的所有視圖。
  • 它們不會(huì)代替你生成響應(yīng)本身,這可能要花一些代價(jià)。
  • 它們只適用于HTTP GET 請(qǐng)求。

在這里,你應(yīng)該選擇最適用于你特定問(wèn)題的工具。如果你有辦法快速計(jì)算出ETag和修改時(shí)間,并且如果一些視圖需要花一些時(shí)間來(lái)生成內(nèi)容,你應(yīng)該考慮使用這篇文檔描述的condition裝飾器。如果一些都執(zhí)行得非??欤瑘?jiān)持使用中間件在如果視圖沒(méi)有修改的條件下也會(huì)使發(fā)回客戶端的網(wǎng)絡(luò)流量也會(huì)減少。

譯者:Django 文檔協(xié)作翻譯小組,原文:Conditional content processing

本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請(qǐng)保留作者署名和文章出處。

Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。