動態網站的問題就在於它是動態的。 也就是說每次用戶訪問一個頁面,服務器要執行數據庫查詢,啓動模板,執行業務邏輯以及最終生成一個你所看到的網頁,這一切都是動態即時生成的。 從處理器資源的角度來看,這是比較昂貴的。python
對於大多數網絡應用來講,過載並非大問題。 由於大多數網絡應用並非washingtonpost.com或Slashdot;它們一般是很小很簡單,或者是中等規模的站點,只有不多的流量。 可是對於中等至大規模流量的站點來講,儘量地解決過載問題是很是必要的。數據庫
這就須要用到緩存了。apache
緩存的目的是爲了不重複計算,特別是對一些比較耗時間、資源的計算。 下面的僞代碼演示瞭如何對動態頁面的結果進行緩存。django
given a URL, try finding that page in the cache if the page is in the cache: return the cached page else: generate the page save the generated page in the cache (for next time) return the generated page
爲此,Django提供了一個穩定的緩存系統讓你緩存動態頁面的結果,這樣在接下來有相同的請求就能夠直接使用緩存中的數據,避免沒必要要的重複計算。 另外Django還提供了不一樣粒度數據的緩存,例如: 你能夠緩存整個頁面,也能夠緩存某個部分,甚至緩存整個網站。後端
Django也和」上游」緩存工做的很好,例如Squid(http://www.squid-cache.org)和基於瀏覽器的緩存。 這些類型的緩存你不直接控制,可是你能夠提供關於你的站點哪部分應該被緩存和怎樣緩存的線索(經過HTTP頭部)給它們瀏覽器
緩存系統須要一些少許的設定工做。 也就是說,你必須告訴它緩存的數據應該放在哪裏,在數據庫中,在文件系統,或直接在內存中。 這是一個重要的決定,影響您的高速緩存的性能,是的,有些類型的緩存比其它類型快。緩存
緩存設置在settings文件的 CACHE_BACKEND
中。 這裏是一個CACHE_BACKEND全部可用值的解釋。安全
Memcached是迄今爲止可用於Django的最快,最有效的緩存類型,Memcached是徹底 基於內存的緩存框架,最初開發它是用以處理高負荷的LiveJournal.com隨後由Danga Interactive公司開源。 它被用於一些站點,例如Facebook和維基百科網站,以減小數據庫訪問,並大幅提升站點的性能。服務器
Memcached是免費的(http://danga.com/memcached)。它做爲一個守 護進程運行,並分配了特定數量的內存。 它只是提供了添加,檢索和刪除緩存中的任意數據的高速接口。 全部數據都直接存儲在內存中,因此沒有對使用的數據庫或文件系統的開銷。cookie
在安裝了Memcached自己以後,你將須要安裝Memcached Python綁定,它沒有直接和Django綁定。 這兩個可用版本。 選擇和安裝如下模塊之一:
最快的可用選項是一個模塊,稱爲cmemcache,在http://gijsbert.org/cmemcache。
若是您沒法安裝cmemcache, 您能夠安裝python - Memcached,在ftp://ftp.tummy.com/pub/python-memcached/。若是該網址已再也不有效,只要到 Memcached的網站http://www.danga.com/memcached/),並從客戶端API完成Python綁定。
若要使用Memcached的Django,設置CACHE_BACKEND到memcached:/ / IP:port/,其中IP是Memcached的守護進程的IP地址,port是Memcached運行的端口。
在這個例子中,Memcached運行在本地主機 (127.0.0.1)上,端口爲11211:
CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
Memcached的一個極好的特性是它在多個服務器間分享緩存的能力。 這意味着您能夠在多臺機器上運行Memcached的守護進程,該程序會把這些機器當成一個單一緩存,而無需重複每臺機器上的緩存值。 要充分利用此功能,請在CACHE_BACKEND裏引入全部服務器的地址,用分號分隔。
這個例子中,緩存在運行在IP地址爲172.19.26.240和172.19.26.242,端口號爲11211的Memcached實例間分享:
CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/'
這個例子中,緩存在運行在172.19.26.240(端口11211),172.19.26.242(端口11212),172.19.26.244(端口11213)的Memcached實例間分享:
CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11212;172.19.26.244:11213/'
最後有關Memcached的一點是,基於內存的緩存有一個重大的缺點。 因爲緩存的數據存儲在內存中,因此若是您的服務器崩潰,數據將會消失。 顯然,內存不是用來持久化數據的,所以不要把基於內存的緩存做爲您惟一的存儲數據緩存。 毫無疑問,在Django的緩存後端不該該用於持久化,它們原本就被設計成緩存的解決方案。但咱們仍然指出此點,這裏是由於基於內存的緩存是暫時的。
爲了使用數據庫表做爲緩存後端,首先在數據庫中運行這個命令以建立緩存表:
python manage.py createcachetable [cache_table_name]
這裏的[cache_table_name]是要建立的數據庫表名。 (這個名字隨你的便,只要它是一個有效的表名,並且不是已經在您的數據庫中使用的表名。)這個命令以Django的數據庫緩存系統所指望的格式建立一個表。
一旦你建立了數據庫表,把你的CACHE_BACKEND設置爲」db://tablename」,這裏的tablename是數據庫表的名字,在這個例子中,緩存表名爲my_cache_table: 在這個例子中,高速緩存表的名字是my_cache_table:
CACHE_BACKEND = 'db://my_cache_table'
數據庫緩存後端使用你的settings文件指定的同一數據庫。 你不能爲你的緩存表使用不一樣的數據庫後端.
若是你已經有了一個快速,良好的索引數據庫服務器,那麼數據庫緩存的效果最明顯。
要把緩存項目放在文件系統上,請爲CACHE_BACKEND使用」file://「的緩存類型。例如,要把緩存數據存儲在/var/tmp/django_cache上,請使用此設置:
CACHE_BACKEND = 'file:///var/tmp/django_cache'
注意例子中開頭有三個斜線。 頭兩項是file://,第三個是第一個字符的目錄路徑,/var/tmp/django_cache。若是你使用的是Windows,在file://以後加上文件的驅動器號:
file://c:/foo/bar
目錄路徑應該是*絕對*路徑,即應該以你的文件系統的根開始。 在設置的結尾放置斜線與否可有可無。
確認該設置指向的目錄存在而且你的Web服務器運行的系統的用戶能夠讀寫該目錄。 繼續上面的例子,若是你的服務器以用戶apache運行,確認/var/tmp/django_cache存在而且用戶apache能夠讀寫/var /tmp/django_cache目錄。
每一個緩存值將被存儲爲單獨的文件,其內容是Python的pickle模塊以序列化(「pickled」)形式保存的緩存數據。 每一個文件的名稱是緩存鍵,以規避開安全文件系統的使用。
若是你想利用內存緩存的速度優點,但又不能使用Memcached,能夠考慮使用本地存儲器緩存後端。 此緩存的多進程和線程安全。 設置 CACHE_BACKEND
爲 locmem:///
來使用它,例如:
CACHE_BACKEND = 'locmem:///'
請注意,每一個進程都有本身私有的緩存實例,這意味着跨進程緩存是不可能的。 這顯然也意味着本地內存緩存效率並非特別高,因此對產品環境來講它可能不是一個好選擇。 對開發來講還不錯。
最後,Django提供了一個假緩存(只是實現了緩存接口,實際上什麼都不作)。
假如你有一個產品站點,在許多地方使用高度緩存,但在開發/測試環境中,你不想緩存,也不想改變代碼,這就很是有用了。 要激活虛擬緩存,就像這樣設置CACHE_BACKEND:
CACHE_BACKEND = 'dummy:///'
儘管Django包含對許多緩存後端的支持,在某些狀況下,你仍然想使用自定義緩存後端。 要讓Django使用外部緩存後端,須要使用一個Python import路徑做爲的CACHE_BACKEND URI的(第一個冒號前的部分),像這樣:
CACHE_BACKEND = 'path.to.backend://'
若是您構建本身的後端,你能夠參考標準緩存後端的實現。 源代碼在Django的代碼目錄的django/core/cache/backends/下。
注意 若是沒有一個真正使人信服的理由,好比主機不支持,你就應該堅持使用Django包含的緩存後端。 它們通過大量測試,而且易於使用。
每一個緩存後端均可能使用參數。 它們在CACHE_BACKEND設置中以查詢字符串形式給出。 有效參數以下:
timeout
:用於緩存的過時時間,以秒爲單位。 這個參數默認被設置爲300秒(五分鐘)。max_entries:對於內存,文件系統和數據庫後端,高速緩存容許的最大條目數,超出這個數則舊值將被刪除。 這個參數默認是300。
cull_percentage
:當達到max_entries
的時候,被刪除的條目比率。 實際的比率是1/cull_percentage
,因此設置cull_frequency=2就是在達到max_entries
的時候去除一半數量的緩存。把
cull_frequency
的值設置爲0
意味着當達到max_entries
時,緩存將被清空。 這將以不少緩存丟失爲代價,大大提升接受訪問的速度。
在這個例子中, timeout
被設成 60
CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=60"
而在這個例子中, timeout
設爲 30
而 max_entries
爲 400
:
CACHE_BACKEND = "locmem:///?timeout=30&max_entries=400"
其中,非法的參數與非法的參數值都將被忽略。
一旦高速緩存設置,最簡單的方法是使用緩存緩存整個網站。 您 須要添加’django.middleware.cache.UpdateCacheMiddleware’和 ‘django.middleware.cache.FetchFromCacheMiddleware’到您的MIDDLEWARE_CLASSES設置中,在這個例子中是:
MIDDLEWARE_CLASSES = ( 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', )
注意:
不,這裏並無排版錯誤: 修改的中間件,必須放在列表的開始位置,而fectch中間件,必須放在最後。 細節有點費解,若是您想了解完整內幕請參看下面的MIDDLEWARE_CLASSES順序。
而後,在你的Django settings文件里加入下面所需的設置:
CACHE_MIDDLEWARE_SECONDS
:每一個頁面應該被緩存的秒數。
CACHE_MIDDLEWARE_KEY_PREFIX
:若是緩存被多個使用相同Django安裝的網站所共享,那麼把這個值設成當前網站名,或其餘能表明這個Django實例的惟一字符串,以免key發生衝突。 若是你不在乎的話能夠設成空字符串。
緩存中間件緩存每一個沒有GET或者POST參數的頁面。 或者,若是CACHE_MIDDLEWARE_ANONYMOUS_ONLY設置爲True,只有匿名請求(即不是由登陸的用戶)將被緩存。 若是想取消用戶相關頁面(user-specific pages)的緩存,例如Djangos 的管理界面,這是一種既簡單又有效的方法。 CACHE_MIDDLEWARE_ANONYMOUS_ONLY,你應該確保你已經啓動AuthenticationMiddleware。
此外,緩存中間件爲每一個HttpResponse自動設置了幾個頭部信息:
當一個新(沒緩存的)版本的頁面被請求時設置Last-Modified頭部爲當前日期/時間。
設置Expires頭部爲當前日期/時間加上定義的CACHE_MIDDLEWARE_SECONDS。
設置Cache-Control頭部來給頁面一個最長的有效期,值來自於CACHE_MIDDLEWARE_SECONDS設置。
參閱更多的中間件第17章。
若是視圖設置本身的緩存到期時間(即 它有一個最大年齡在頭部信息的Cache-Control
中), 那麼頁面將緩存直到過時,而不是CACHE_MIDDLEWARE_SECONDS。使用django.views.decorators.cache裝 飾器,您能夠輕鬆地設置視圖的到期時間(使用cache_control裝飾器)或禁用緩存視圖(使用never_cache裝飾器)。 請參閱下面的」使用其餘頭部信息「小節以瞭解裝飾器的更多信息。
更加顆粒級的緩存框架使用方法是對單個視圖的輸出進行緩存。 django.views.decorators.cache
定義了一個自動緩存視圖響應的cache_page
裝飾器。 他是很容易使用的:
from django.views.decorators.cache import cache_page def my_view(request): # ... my_view = cache_page(my_view, 60 * 15)
也可使用Python2.4的裝飾器語法:
@cache_page(60 * 15) def my_view(request): # ...
cache_page
只接受一個參數: 以秒計的緩存超時時間。 在前例中, 「my_view()」 視圖的結果將被緩存 15 分鐘。 (注意: 爲了提升可讀性,該參數被書寫爲 60 * 15
。 60 * 15
將被計算爲 900
,也就是說15 分鐘乘以每分鐘 60 秒。)
和站點緩存同樣,視圖緩存與 URL 無關。 若是多個 URL 指向同一視圖,每一個視圖將會分別緩存。 繼續 my_view
範例,若是 URLconf 以下所示:
urlpatterns = ('', (r'^foo/(\d{1,2})/$', my_view), )
那麼正如你所期待的那樣,發送到 /foo/1/
和 /foo/23/
的請求將會分別緩存。 但一旦發出了特定的請求(如: /foo/23/ ),以後再度發出的指向該 URL 的請求將使用緩存。
前一節中的範例將視圖硬編碼爲使用緩存,由於 cache_page
在適當的位置對 my_view
函數進行了轉換。 該方法將視圖與緩存系統進行了耦合,從幾個方面來講並不理想。 例如,你可能想在某個無緩存的站點中重用該視圖函數,或者你可能想將該視圖發佈給那些不想經過緩存使用它們的人。 解決這些問題的方法是在 URLconf 中指定視圖緩存,而不是緊挨着這些視圖函數自己來指定。
完成這項工做很是簡單: 在 URLconf 中用到這些視圖函數的時候簡單地包裹一個 cache_page
。如下是剛纔用到過的 URLconf : 這是以前的URLconf:
urlpatterns = ('', (r'^foo/(\d{1,2})/$', my_view), )
如下是同一個 URLconf ,不過用 cache_page
包裹了 my_view
:
from django.views.decorators.cache import cache_page urlpatterns = ('', (r'^foo/(\d{1,2})/$', cache_page(my_view, 60 * 15)), )
若是採起這種方法, 不要忘記在 URLconf 中導入 cache_page
。
你一樣可使用cache
標籤來緩存模板片斷。 在模板的頂端附近加入{% load cache %}
以通知模板存取緩存標籤。
模板標籤{% cache %}
在給定的時間內緩存了塊的內容。 它至少須要兩個參數: 緩存超時時間(以秒計)和指定緩存片斷的名稱。 示例:
{% load cache %} {% cache 500 sidebar %} .. sidebar .. {% endcache %}
有時你可能想緩存基於片斷的動態內容的多份拷貝。 好比,你想爲上一個例子的每一個用戶分別緩存側邊欄。 這樣只須要給{% cache %}
傳遞額外的參數以標識緩存片斷。
{% load cache %} {% cache 500 sidebar request.user.username %} .. sidebar for logged in user .. {% endcache %}
傳遞不止一個參數也是可行的。 簡單地把參數傳給{% cache %}
。
緩存超時時間能夠做爲模板變量,只要它能夠解析爲整數值。 例如,若是模板變量my_timeout
值爲600,那麼如下兩個例子是等價的。
{% cache 600 sidebar %} ... {% endcache %} {% cache my_timeout sidebar %} ... {% endcache %}
這個特性在避免模板重複方面很是有用。 能夠把超時時間保存在變量裏,而後在別的地方複用。
有些時候,對整個經解析的頁面進行緩存並不會給你帶來太多好處,事實上可能會過猶不及。
好比說,也許你的站點所包含的一個視圖依賴幾個費時的查詢,每隔一段時間結果就會發生變化。 在這種狀況下,使用站點級緩存或者視圖級緩存策略所提供的整頁緩存並非最理想的,由於你可能不會想對整個結果進行緩存(由於一些數據常常變化),但你仍 然會想對不多變化的部分進行緩存。
針對這樣的狀況,Django提供了簡單低級的緩存API。 你能夠經過這個API,以任何你須要的粒度來緩存對象。 你能夠對全部可以安全進行 pickle 處理的 Python 對象進行緩存: 字符串、字典和模型對象列表等等。 (查閱 Python 文檔能夠了解到更多關於 pickling 的信息。)
緩存模塊django.core.cache
擁有一個自動依據CACHE_BACKEND
設置建立的django.core.cache
對象。
>>> from django.core.cache import cache
基本的接口是 set(key, value, timeout_seconds)
和 get(key)
:
>>> cache.set('my_key', 'hello, world!', 30) >>> cache.get('my_key') 'hello, world!'
timeout_seconds
參數是可選的, 而且默認爲前面講過的 CACHE_BACKEND
設置中的 timeout
參數.
若是緩存中不存在該對象,那麼cache.get()
會返回None
。
# Wait 30 seconds for 'my_key' to expire... >>> cache.get('my_key') None
咱們不建議在緩存中保存 None
常量,由於你將沒法區分你保存的 None
變量及由返回值 None
所標識的緩存未命中。
cache.get()
接受一個 缺省
參數。 它指定了當緩存中不存在該對象時所返回的值:
>>> cache.get('my_key', 'has expired') 'has expired'
使用add()
方法來新增一個原來沒有的鍵值。 它接受的參數和set()
同樣,可是並不去嘗試更新已經存在的鍵值。
>>> cache.set('add_key', 'Initial value') >>> cache.add('add_key', 'New value') >>> cache.get('add_key') 'Initial value'
若是想肯定add()
是否成功添加了緩存值,你應該測試返回值。 成功返回True,失敗返回False。
還有個get_many()
接口。 get_many()
所返回的字典包括了你所請求的存在於緩存中且未超時的全部鍵值。
>>> cache.set('a', 1) >>> cache.set('b', 2) >>> cache.set('c', 3) >>> cache.get_many(['a', 'b', 'c']) {'a': 1, 'b': 2, 'c': 3}
最後,你能夠用 cache.delete()
顯式地刪除關鍵字。
>>> cache.delete('a')
也可使用incr()
或者decr()
來增長或者減小已經存在的鍵值。 默認狀況下,增長或減小的值是1。能夠用參數來制定其餘值。 若是嘗試增減不存在的鍵值會拋出ValueError。
>>> cache.set('num', 1) >>> cache.incr('num') 2 >>> cache.incr('num', 10) 12 >>> cache.decr('num') 11 >>> cache.decr('num', 5) 6
注意
incr()
/decr()
方法不是原子操做。 在支持原子增減的緩存後端上(最著名的是memcached),增減操做纔是原子的。 然而,若是後端並不原生支持增減操做,也能夠經過取值/更新兩步操做來實現。
目前爲止,本章的焦點一直是對你 本身的 數據進行緩存。 但還有一種與 Web 開發相關的緩存: 上游緩存。 有一些系統甚至在請求到達站點以前就爲用戶進行頁面緩存。
下面是上游緩存的幾個例子:
你的 ISP (互聯網服務商)可能會對特定的頁面進行緩存,所以若是你向 http://example.com/ 請求一個頁面,你的 ISP 可能無需直接訪問 example.com 就能將頁面發送給你。 而 example.com 的維護者們卻無從得知這種緩存,ISP 位於 example.com 和你的網頁瀏覽器之間,透明地處理全部的緩存。
你的 Django 網站可能位於某個 代理緩存 以後,例如 Squid 網頁代理緩存 (http://www.squid-cache.org/),該緩存爲提升性能而對頁面進行緩存。 在此狀況下 ,每一個請求將首先由代理服務器進行處理,而後僅在須要的狀況下才被傳遞至你的應用程序。
你的網頁瀏覽器也對頁面進行緩存。 若是某網頁送出了相應的頭部,你的瀏覽器將在爲對該網頁的後續的訪問請求使用本地緩存的拷貝,甚至不會再次聯繫該網頁查看是否發生了變化。
上游緩存將會產生很是明顯的效率提高,但也存在必定風險。 許多網頁的內容依據身份驗證以及許多其餘變量的狀況發生變化,緩存系統僅盲目地根據 URL 保存頁面,可能會向這些頁面的後續訪問者暴露不正確或者敏感的數據。
舉個例子,假定你在使用網頁電郵系統,顯然收件箱頁面的內容取決於登陸的是哪一個用戶。 若是 ISP 盲目地緩存了該站點,那麼第一個用戶經過該 ISP 登陸以後,他(或她)的用戶收件箱頁面將會緩存給後續的訪問者。 這一點也很差玩。
幸運的是, HTTP 提供瞭解決該問題的方案。 已有一些 HTTP 頭標用於指引上游緩存根據指定變量來區分緩存內容,並通知緩存機制不對特定頁面進行緩存。 咱們將在本節後續部分將對這些頭標進行闡述。
Vary
頭部定義了緩存機制在構建其緩存鍵值時應當將哪一個請求頭標考慮在內。 例如,若是網頁的內容取決於用戶的語言偏好,該頁面被稱爲根據語言而不一樣。
缺省狀況下,Django 的緩存系統使用所請求的路徑(好比:"/stories/2005/jun/23/bank_robbed/"
)來建立其緩存鍵。這意味着每次請求都會使用一樣的緩存版本,不考慮才客戶端cookie和語言配置的不一樣。 除非你使用Vary
頭部通知緩存機制頁面輸出要依據請求頭裏的cookie,語言等的設置而不一樣。
要在 Django 完成這項工做,可以使用便利的 vary_on_headers
視圖裝飾器,以下所示:
from django.views.decorators.vary import vary_on_headers # Python 2.3 syntax. def my_view(request): # ... my_view = vary_on_headers(my_view, 'User-Agent') # Python 2.4+ decorator syntax. @vary_on_headers('User-Agent') def my_view(request): # ...
在這種狀況下,緩存機制(如 Django 本身的緩存中間件)將會爲每個單獨的用戶瀏覽器緩存一個獨立的頁面版本。
使用 vary_on_headers
裝飾器而不是手動設置 Vary
頭部(使用像 response['Vary'] = 'user-agent'
之類的代碼)的好處是修飾器在(可能已經存在的) Vary 之上進行 添加
,而不是從零開始設置,且可能覆蓋該處已經存在的設置。
你能夠向 vary_on_headers()
傳入多個頭標:
@vary_on_headers('User-Agent', 'Cookie') def my_view(request): # ...
該段代碼通知上游緩存對 二者 都進行不一樣操做,也就是說 user-agent 和 cookie 的每種組合都應獲取本身的緩存值。 舉例來講,使用 Mozilla
做爲 user-agent 而 foo=bar
做爲 cookie 值的請求應該和使用 Mozilla
做爲 user-agent 而 foo=ham
的請求應該被視爲不一樣請求。
因爲根據 cookie 而區分對待是很常見的狀況,所以有 vary_on_cookie
裝飾器。 如下兩個視圖是等效的:
@vary_on_cookie def my_view(request): # ... @vary_on_headers('Cookie') def my_view(request): # ...
傳入 vary_on_headers
頭標是大小寫不敏感的; "User-Agent"
與 "user-agent"
徹底相同。
你也能夠直接使用幫助函數:django.utils.cache.patch_vary_headers
。 該函數設置或增長 Vary header ,例如:
from django.utils.cache import patch_vary_headers def my_view(request): # ... response = render_to_response('template_name', context) patch_vary_headers(response, ['Cookie']) return response
patch_vary_headers
以一個 HttpResponse
實例爲第一個參數,以一個大小寫不敏感的頭標名稱列表或元組爲第二個參數。
關於緩存剩下的問題是數據的隱私性以及在級聯緩存中數據應該在何處儲存的問題。
一般用戶將會面對兩種緩存: 他或她本身的瀏覽器緩存(私有緩存)以及他或她的提供者緩存(公共緩存)。 公共緩存由多個用戶使用,而受其餘某人的控制。 這就產生了你不想遇到的敏感數據的問題,好比說你的銀行帳號被存儲在公衆緩存中。 所以,Web 應用程序須要以某種方式告訴緩存那些數據是私有的,哪些是公共的。
解決方案是標示出某個頁面緩存應當是私有的。 要在 Django 中完成此項工做,可以使用 cache_control
視圖修飾器: 例如:
from django.views.decorators.cache import cache_control @cache_control(private=True) def my_view(request): # ...
該修飾器負責在後臺發送相應的 HTTP 頭部。
還有一些其餘方法能夠控制緩存參數。 例如, HTTP 容許應用程序執行以下操做:
定義頁面能夠被緩存的最大時間。
指定某個緩存是否老是檢查較新版本,僅當無更新時才傳遞所緩存內容。 (一些緩存即使在服務器頁面發生變化的狀況下仍然會傳送所緩存的內容,只由於緩存拷貝沒有過時。)
在 Django 中,可以使用 cache_control
視圖修飾器指定這些緩存參數。 在本例中, cache_control
告訴緩存對每次訪問都從新驗證緩存並在最長 3600 秒內保存所緩存版本:
from django.views.decorators.cache import cache_control @cache_control(must_revalidate=True, max_age=3600) def my_view(request): # ...
在 cache_control()
中,任何合法的Cache-Control
HTTP 指令都是有效的。下面是完整列表:
public=True
private=True
no_cache=True
no_transform=True
must_revalidate=True
proxy_revalidate=True
max_age=num_seconds
s_maxage=num_seconds
緩存中間件已經使用 CACHE_MIDDLEWARE_SETTINGS
設置設定了緩存頭部 max-age 。 若是你在cache_control修飾器中使用了自定義的max_age,該修飾器將會取得優先權,該頭部的值將被正確地被合併。
若是你想用頭部徹底禁掉緩存,django.views.decorators.cache.never_cache
裝飾器能夠添加確保響應不被緩存的頭部信息。 例如:
from django.views.decorators.cache import never_cache @never_cache def myview(request): # ...
Django 帶有一些其它中間件可幫助您優化應用程序的性能:
django.middleware.http.ConditionalGetMiddleware
爲現代瀏覽器增長了有條件的,基於 ETag
和 Last-Modified
頭標的GET響應的相關支持。
django.middleware.gzip.GZipMiddleware
爲全部現代瀏覽器壓縮響應內容,以節省帶寬和傳送時間。
若是使用緩存中間件,注意在MIDDLEWARE_CLASSES
設置中正確配置。 由於緩存中間件須要知道哪些頭部信息由哪些緩存區來區分。 中間件老是儘量得想Vary
響應頭中添加信息。
UpdateCacheMiddleware
在相應階段運行。由於中間件是以相反順序運行的,全部列表頂部的中間件反而last在相應階段的最後運行。 全部,你須要確保UpdateCacheMiddleware
排在任何可能往Vary頭部添加信息的中間件以前
。 下面的中間件模塊就是這樣的:
添加 Cookie
的 SessionMiddleware
添加 Accept-Encoding
的 GZipMiddleware
添加Accept-Language
的LocaleMiddleware
另外一方面,FetchFromCacheMiddleware
在請求階段運行,這時中間件循序執行,因此列表頂端的項目會首先執行。 FetchFromCacheMiddleware
也須要在會修改Vary
頭部的中間件以後運行,因此FetchFromCacheMiddleware
必須放在它們後面。