這里寫自定義目錄標題
- 訪問緩存
- django.core.cache.caches
- django.core.cache.cache
- 基本用法
- cache.set(key, value, timeout=DEFAULT_TIMEOUT, version=None)
- cache.get(key, default=None, version=None)
- cache.add(key, value, timeout=DEFAULT_TIMEOUT, version=None)
- cache.get_or_set(key, default, timeout=DEFAULT_TIMEOUT, version=None)
- cache.get_many(keys, version=None)
- cache.set_many(dict, timeout)
- cache.delete(key, version=None)
- cache.delete_many(keys, version=None)
- cache.clear()
- cache.touch(key, timeout=DEFAULT_TIMEOUT, version=None)
- cache.incr/decr(key, delta=1, version=None)
- cache.close()
- 緩存前綴
- 緩存版本控制
- 緩存鍵轉換
有時,緩存整個渲染頁面并不會帶來太多好處,事實上,這樣會很不方便。比如站點包含一個視圖,它的結果依賴許多費時的查詢,而且結果會隨著時間變化而改變。在這個情況下,使用站點或視圖緩存策略提供的全頁面緩存并不理想,以為不能緩存所有結果(一些數據經常變動),不過仍然可以緩存幾乎沒有變化的結果。
像這樣的情況Django公開了一個底層的緩存API。可以使用這個API以任意級別顆粒度在緩存中存儲對象。可以緩存任何可以安全的pickle的Python對象:模型對象的字符串、字典、列表或其它(大部分通用的Python對象都可以被pickle)。
訪問緩存
django.core.cache.caches
可以通過類似字典一樣的object:django.core.cache.caches對象訪問在CACHES配置的緩存。重復請求同一個線程里的同一個別名將返回同一個對象。
from django.core.cache import caches
cache1 = caches["myalias"]
cache2 = caches["myalias"]
cache1 is cache2 # True
如果鍵名不存在,將會引發InvalidCacheBackendError錯誤。為了支持線程安全,將為每個線程返回緩存后端不同實例。
django.core.cache.cache
作為一種快捷方式,默認緩存可以通過django.core.cache.cache訪問:from django.core.cache import cache
,這個對象等價于caches['default']
。
基本用法
cache.set(key, value, timeout=DEFAULT_TIMEOUT, version=None)
# 設置緩存
cache.set('my_key', 'hello, world!', 30)
key是一個字符串,value可以任何picklable形式的Python對象。
timeout參數是可選的,默認為CACHES中響應后端的timeout參數。它是值存在緩存里的秒數。timeout設置為None時將永久緩存。timeout為0將不緩存值。
cache.get(key, default=None, version=None)
cache.get('my_key') # hello, world!
如果緩存中不存在該對象,cache.get()
返回None:
# Wait 30 seconds for 'my_key' to expire...
cache.get("my_key") # None
如果需要確定對象是否存在于緩存中,并且您已經存儲了字面值None,可以使用一個特殊的對象作為默認值:
sentinel = object()
cache.get("my_key", sentinel) is sentinel # False
# Wait 30 seconds for 'my_key' to expire...
cache.get("my_key", sentinel) is sentinel # True
cahce.get()
可以接受一個default參數,用于指定在對象不存在于緩存中時返回的值:
cache.get("my_key", "has expired") # 'has expired'
cache.add(key, value, timeout=DEFAULT_TIMEOUT, version=None)
如果只在健不存在時才添加鍵,可以使用add()
方法。它接受與set()
相同的參數,但如果指定的鍵已存在,它不會嘗試更新緩存:
cache.set("add_key", "Initial value") # True
cache.add("add_key", "New value") # False
cache.get("add_key") # 'Initial value'
如果想知道通過add()
存儲的值是否存在緩存中,你可以檢查返回值。如果值已保存,將返回True,否則返回False。
cache.get_or_set(key, default, timeout=DEFAULT_TIMEOUT, version=None)
如果要獲取鍵的值,或者如果鍵不再緩存中則設置一個值,可以使用get_or_set()
方法。它接受與get()
相同的參數,但默認值將作為該鍵的新緩存值設置,而不是返回值:
cache.get("my_new_key") # returns None
cache.get_or_set("my_new_key", "my new value", 100) # 'my new value'
還可以將任何可調用對象作為default值傳遞:
import datetime
cache.get_or_set("some-timestamp-key", datetime.datetime.now) # datetime.datetime(2014, 12, 11, 0, 15, 49, 457920)
cache.get_many(keys, version=None)
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.set_many(dict, timeout)
更高效地設置多個值,可以使用set_many()
來傳遞一個鍵值對的字典:
cache.set_many({"a": 1, "b": 2, "c": 3})
cache.get_many(["a", "b", "c"]) # {'a': 1, 'b': 2, 'c': 3}
類似cache.set()
,set_many()
帶有一個可選的timeout參數。在已支持的后端(memcached),set_many()
會返回無法插入的鍵列表。
cache.delete(key, version=None)
delete()
明確刪除鍵,以清除特定對象的緩存:
cache.delete("a") # True
如果鍵被成功刪除,將返回True,否則返回False
cache.delete_many(keys, version=None)
如果想一次性清除一組鍵,可以使用delete_manay()
方法,并傳入要清除的鍵列表:
cahce.delete_many(['a', 'b', 'c']])
cache.clear()
如果想刪除緩存中所有的鍵,可以使用cache.clear()
。注意,clear()
會從緩存中刪除所有內容,不僅僅是自己應用程序設置的鍵:
cache.touch(key, timeout=DEFAULT_TIMEOUT, version=None)
設置鍵的新過期時間,例如要將鍵更新為在10秒后過期:
cache.touch('a', 10) # True
和其他方法一樣,timeout參數是可選的,并且默認是CACHES設置的響應后端的TIMEOUT選項。
如果鍵被成功touch()
,將返回True,否則返回False。
cache.incr/decr(key, delta=1, version=None)
可以使用incr()或decr()方法來分別遞增或遞減已存在的鍵。默認情況下現有的緩存值將遞增或遞減1,通過在遞增、遞減調用中提供參數來指定其他遞增、遞減的值。如果嘗試遞增或遞減不存在的鍵,則會引發ValueError:
cache.set("num", 1)
cache.incr("num") # 2
cache.incr("num", 10) # 12cache.decr("num") # 11
cache.decr("num", 5) # 6
提示:不保證incr()
、decr()
方法是原子的。那些后端支持原子遞增、遞減(最值得注意的時memecached后端),則遞增和遞減操作是原子的,然而如果后端本身沒有提供遞增、遞減方法,則將使用檢索和更新兩步來實現
cache.close()
如果緩存后端已經實現了close()
方法,可以關閉緩存的連接。
對于沒有實現close方法的緩存,它將無效操作。
緩存前綴
如果正在服務器之間或者生產、開發緩存之間共享緩存實例,有可能會使得一個服務器使用另一個服務器的緩存數據。如果緩存數據格式是相同的,這會導致一些難以診斷的問題。
為了防止這個問題,Django為單臺服務器提供了為素有緩存鍵提供前綴的方法。當一個特殊的緩存鍵被保存或檢索時,Django會為緩存自動添加KEY_PREFIX緩存設置的前綴。
要確保每個Django實例有不同的KEY_PREFIX,這樣就保證緩存值不會發生沖突。
KEY_PREFIX默認’'(空字符串)。
緩存版本控制
當更改使用緩存值的運行代碼時,可能需要清除任何已存在的緩存值。最簡單方法是刷新整個緩存,但這會導致那些仍然有用且有效的緩存值。
Django提供更好的方式來指向單個緩存值。Django緩存框架有一個系統范圍的版本標識,需要在VERSION緩存配置中指定,這個配置的值將自動與緩存前綴和用戶提供的緩存鍵組合起來獲得最終的緩存鍵。
默認情況下,任何鍵請求都會自動包含站點默認的緩存版本,但是原始緩存函數都包含一個version參數,因此可以指定要設置或獲取的特定緩存鍵版本,例如:
# Set version 2 of a cache key
cache.set("my_key", "hello world!", version=2)
# Get the default version (assuming version=1)
cache.get("my_key") # None
# Get version 2 of the same key
cache.get("my_key", version=2) # 'hello world!'
可以使用incr_version()
和decr_version()
方法遞增和遞減特定鍵的版本。這使得將特定鍵提示到新版本,而不影響其他鍵。繼續之前的示例:
# Increment the version of 'my_key'
cache.incr_version("my_key")
# The default version still isn't available
cache.get("my_key") # None
# Version 2 isn't available, either
cache.get("my_key", version=2) # None
# But version 3 *is* available
cache.get("my_key", version=3) # 'hello world!'
緩存鍵轉換
用戶提供的緩存鍵不是單獨使用的,它是與緩存前綴、鍵版本組合后獲取最終緩存鍵。默認情況下,使用冒號連接這三部分生成最終的字符串:
def make_key(key, key_prefix, version):return "%s:%s:%s" % (key_prefix, version, key)
如果想用不同方式組合,或者應用其他處理來獲得最終的鍵(比如,獲得關鍵部分的哈希摘要),那么可以提供一個自定義鍵函數。
KEY_FUNCATION緩存設置指定一個與上面的make_key()
原型匹配的函數路徑。如果提供,這個自定義鍵函數將替代默認的鍵組合函數來使用。