Django使用缓存笔记
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
Django設(shè)置緩存需要在settings.py文件中進(jìn)行設(shè)置,緩存配置是通過setting文件的CACHES 配置來實(shí)現(xiàn)的。?
Memcached
需要在Django中使用Memcached時(shí):
將 BACKEND 設(shè)置為django.core.cache.backends.memcached.MemcachedCache或者django.core.cache.backends.memcached.PyLibMCCache (取決于你所選綁定memcached的方式)
將LOCATION設(shè)置為ip:port值,ip是Memcached守護(hù)進(jìn)程的ip地址,port是Memcached運(yùn)行的端口。或者設(shè)置為unix:path值,path是Memcached Unix socket file的路徑.
在這個(gè)例子中,Memcached 運(yùn)行再 本地 (127.0.0.1) 的11211端口,使用 python-memcached(也就是需要這么一個(gè)python插件) 綁定:
這個(gè)例子中,Memcached 通過一個(gè)本地的Unix socket file/tmp/memcached.sock 來交互,也要使用python-memcached綁定:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache','LOCATION': 'unix:/tmp/memcached.sock','options': {'MAX_ENTRIES': 10240,},} }Memcached有一個(gè)非常好的特點(diǎn)就是可以讓幾個(gè)服務(wù)的緩存共享。 這就意味著你可以再幾個(gè)物理機(jī)上運(yùn)行Memcached服務(wù),這些程序?qū)堰@幾個(gè)機(jī)器當(dāng)做 同一個(gè) 緩存,從而不需要復(fù)制每個(gè)緩存的值在每個(gè)機(jī)器上。為了使用這個(gè)特性,把所有的服務(wù)地址放在LOCATION里面,用分號隔開或者當(dāng)做一個(gè)list。
這個(gè)例子,緩存共享在2個(gè)Memcached 實(shí)例中,IP地址為172.19.26.240 和 172.19.26.242,端口同為11211:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache','LOCATION': ['172.19.26.240:11211','172.19.26.242:11211',],'options': {'MAX_ENTRIES': 10240,},} }下面的這個(gè)例子,緩存通過下面幾個(gè) ?Memcached 實(shí)例共享,IP地址為172.19.26.240 (端口 11211), 172.19.26.242 (端口 11212), and 172.19.26.244 (端口 11213):
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache','LOCATION': ['172.19.26.240:11211','172.19.26.242:11212','172.19.26.244:11213',],'options': {'MAX_ENTRIES': 10240,},} }數(shù)據(jù)庫緩存
Django可以把緩存保存在你的數(shù)據(jù)庫里。如果你有一個(gè)快速的、專業(yè)的數(shù)據(jù)庫服務(wù)器的話那這種方式是效果最好的。
為了把數(shù)據(jù)表用來當(dāng)做你的緩存后臺:
把BACKEND設(shè)置為django.core.cache.backends.db.DatabaseCache
把 LOCATION 設(shè)置為 tablename, 數(shù)據(jù)表的名稱。這個(gè)名字可以是任何你想要的名字,只要它是一個(gè)合法的表名并且在你的數(shù)據(jù)庫中沒有被使用過。
在這個(gè)示例中,緩存表的名字是 my_cache_table:
創(chuàng)建緩存表
使用數(shù)據(jù)庫緩存之前,你必須用這個(gè)命令來創(chuàng)建緩存表:
python manage.py createcachetable這將在你的數(shù)據(jù)庫中創(chuàng)建一個(gè)Django的基于數(shù)據(jù)庫緩存系統(tǒng)預(yù)期的特定格式的數(shù)據(jù)表。
本地內(nèi)存緩存
這是默認(rèn)的緩存,如果你不在指定其他的緩存設(shè)置。如果你想要具有高速這個(gè)有點(diǎn)的基于內(nèi)存的緩存但是又沒有能力帶動 Memcached, 那就考慮一下本地緩存吧。這個(gè)緩存是per-process(見下文)和線程安全的。要使用它,請將BACKEND設(shè)置為"django.core.cache.backends.locmem.LocMemCache"。例如:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache','LOCATION': 'unique-snowflake','options': {'MAX_ENTRIES': 10240,},} }高速緩存LOCATION用于標(biāo)識各個(gè)存儲器存儲。如果您只有一個(gè)locmem快取,可以省略LOCATION;然而,如果您有多個(gè)本地內(nèi)存緩存,您將需要為其中至少一個(gè)分配一個(gè)名稱,以保持它們分離。
注意每個(gè)進(jìn)程都有自己的私有緩存實(shí)例,這意味著不可能有跨進(jìn)程緩存。這顯然也意味著本地內(nèi)存緩存不是特別高效的內(nèi)存,因此它可能不是生產(chǎn)環(huán)境的好選擇。
Cache 參數(shù)
TIMEOUT
緩存的默認(rèn)過期時(shí)間,以秒為單位,這個(gè)參數(shù)默認(rèn)是300seconds (5 分鐘).
你可以設(shè)置TIMEOUT為None這樣的話,緩存默認(rèn)永遠(yuǎn)不會過期。值設(shè)置成0造成緩存立即失效(緩存就沒有意義了)。
OPTIONS
這個(gè)參數(shù)應(yīng)該被傳到緩存后端。有效的可選項(xiàng)列表根據(jù)緩存的后端不同而不同,由第三方庫所支持的緩存將會把這些選項(xiàng)直接配置到底層的緩存庫。
緩存的后端實(shí)現(xiàn)自己的選擇策略,常見的選項(xiàng):
MAX_ENTRIES
高速緩存允許的最大條目數(shù),超出這個(gè)數(shù)則舊值將被刪除. 這個(gè)參數(shù)默認(rèn)是300.
CULL_FREQUENCY
當(dāng)達(dá)到MAX_ENTRIES的時(shí)候,被刪除的條目比率。實(shí)際比率是1/CULL_FREQUENCY,所以設(shè)置CULL_FREQUENCY為2會在達(dá)到MAX_ENTRIES 所設(shè)置值時(shí)刪去一半的緩存。這個(gè)參數(shù)應(yīng)該是整數(shù),默認(rèn)為 3.
把 CULL_FREQUENCY的值設(shè)置為 0 意味著當(dāng)達(dá)到MAX_ENTRIES時(shí),緩存將被清空。某些緩存后端 (database尤其)這將以很多緩存丟失為代價(jià),大大much 提高接受訪問的速度。
KEY_PREFIX
將自動包含(默認(rèn)情況下預(yù)置為)Django服務(wù)器使用的所有緩存鍵的字符串。
VERSION
由Django服務(wù)器生成的緩存鍵的默認(rèn)版本號。
KEY_FUNCTION
包含函數(shù)的虛線路徑的字符串,定義如何將前綴,版本和鍵組成最終緩存鍵。
在下面這個(gè)例子中,一個(gè)文件系統(tǒng)緩存后端,緩存過期時(shí)間被設(shè)置為60秒,最大條目為1000.
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache','LOCATION': '/var/tmp/django_cache','TIMEOUT': 60,'OPTIONS': {'MAX_ENTRIES': 1000}} }站點(diǎn)級緩存
一旦高速緩存設(shè)置,最簡單的方法是使用緩存緩存整個(gè)網(wǎng)站。你需要把'django.middleware.cache.UpdateCacheMiddleware' 和 'django.middleware.cache.FetchFromCacheMiddleware' 添加到你的MIDDLEWARE_CLASSES設(shè)置里, 如例子所示:
MIDDLEWARE_CLASSES = ('django.middleware.cache.UpdateCacheMiddleware','django.middleware.common.CommonMiddleware','django.middleware.cache.FetchFromCacheMiddleware', )'update'中間件,必須放在列表的開始位置,而fectch中間件,必須放在最后。
然后,添加下面這些需要的參數(shù)到settings文件里:
CACHE_MIDDLEWARE_ALIAS
用于存儲的緩存的別名
CACHE_MIDDLEWARE_SECONDS
每個(gè)page需要被緩存多少秒
CACHE_MIDDLEWARE_KEY_PREFIX
如果緩存被使用相同Django安裝的多個(gè)網(wǎng)站所共享,那么把這個(gè)值設(shè)成當(dāng)前網(wǎng)站名,或其他能代表這個(gè)Django實(shí)例的唯一字符串,以避免key發(fā)生沖突。 如果你不在意的話可以設(shè)成空字符串。
FetchFromCacheMiddleware緩存GET和HEAD狀態(tài)為200的回應(yīng),用不同的參數(shù)請求相同的url被視為獨(dú)立的頁面,緩存是分開的。
另外, UpdateCacheMiddleware在每個(gè)HttpResponse里自動設(shè)置了一些頭部信息
設(shè)置Last-Modified 當(dāng)一個(gè)新(沒緩存的)版本的頁面被請求時(shí),為當(dāng)前日期/時(shí)間
設(shè)置 Expires 頭 為當(dāng)前日期/時(shí)間加上定義的CACHE_MIDDLEWARE_SECONDS.
設(shè)置 Cache-Control頭部來給頁面一個(gè)最長的有效期, 來自 CACHE_MIDDLEWARE_SECONDS 的設(shè)置.
單個(gè)view緩存
django.views.decorators.cache.cache_page()更加輕巧的緩存框架使用方法是對單個(gè)有效視圖的輸出進(jìn)行緩存。 django.views.decorators.cache 定義了一個(gè)自動緩存視圖響應(yīng)的 cache_page裝飾器,使用非常簡單:
from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request):...cache_page接受一個(gè)參數(shù):timeout,秒為單位。在前例中,“my_view()”視圖的結(jié)果將被緩存15分鐘(注意為了提高可讀性我們寫了60 * 15等于 900也就是說15分鐘等于60秒乘15.)
和站點(diǎn)緩存一樣,視圖緩存與 URL 無關(guān)。如果多個(gè)URL指向同一視圖,每個(gè)URL將會分別緩存。
在URLconf中指定每個(gè)視圖的緩存
將視圖硬編碼為使用緩存,因?yàn)閏ache_page在適當(dāng)?shù)奈恢脤y_view函數(shù)進(jìn)行了轉(zhuǎn)換。該方法將視圖與緩存系統(tǒng)進(jìn)行了耦合,從幾個(gè)方面來說并不理想。例如,你可能想在某個(gè)無緩存的站點(diǎn)中重用該視圖函數(shù),或者不想通過緩存使用頁面的人請求你的頁面。解決這些問題的方法是在URLconf 中指定視圖緩存,而不是在這些視圖函數(shù)上來指定。
這樣做很容易:在URLconf中引用它時(shí),只需用cache_page包裝視圖函數(shù)。這是以前的URLconf:
my_view包裹在cache_page:
模板片段緩存
如果想對緩存進(jìn)行更多的控制,可以使用 cache模板標(biāo)簽來緩存模板的一個(gè)片段。 要讓模板處理這個(gè)標(biāo)簽,把{% load cache %} 放在緩存片段的上面。
標(biāo)簽{% cache %}將按給定的時(shí)間緩存包含塊中的內(nèi)容。它最少需要兩個(gè)參數(shù):緩存時(shí)間(以秒為單位);給緩存片段起的名稱。例如:
{% load cache %} {% cache 500 sidebar %}.. sidebar .. {% endcache %}有時(shí),你可以依據(jù)這個(gè)片段內(nèi)的動態(tài)內(nèi)容緩存多個(gè)版本。如上個(gè)例子中,可以給站點(diǎn)的每個(gè)用戶生成不同版本的sidebar緩存。只需要給 {% cache %}標(biāo)簽再傳遞一個(gè)參數(shù)來標(biāo)識區(qū)分這個(gè)緩存片段。
{% load cache %} {% cache 500 sidebar request.user.username %}.. sidebar for logged in user .. {% endcache %}指定一個(gè)以上的參數(shù)來識別片段是非常好的。 簡單的盡可能的傳遞你需要的參數(shù)到 {% cache %} 。
如果USE_I18N設(shè)置為True,則每個(gè)網(wǎng)站中間件緩存將respect the active language。對于cache模板標(biāo)記,您可以使用模板中提供的translation-specific variables之一來實(shí)現(xiàn)相同的結(jié)果:
{% load i18n %} {% load cache %}{% get_current_language as LANGUAGE_CODE %}{% cache 600 welcome LANGUAGE_CODE %}{% trans "Welcome to example.com" %} {% endcache %}緩存超時(shí)可以是模板變量,只要模板變量解析為整數(shù)值即可。例如,如果模板變量my_timeout設(shè)置為值600,則以下兩個(gè)示例是等效的:
{% cache 600 sidebar %} ... {% endcache %} {% cache my_timeout sidebar %} ... {% endcache %}此功能有助于避免模板中的重復(fù)。您可以在一個(gè)位置設(shè)置變量的超時(shí),只需重復(fù)使用該值。
底層的緩存API
對于這個(gè)情況 Django提供了一個(gè)底層的 cache API. 你可以用這個(gè) API來儲存在緩存中的對象,并且控制粒度隨你喜歡。您可以緩存可以安全pickle的任何Python對象:模型對象的字符串,字典,列表等等。?
訪問緩存
如果key不存在,就會引發(fā)一個(gè) InvalidCacheBackendError 。
基本用法
>>> cache.set('my_key', 'hello, world!', 30) >>> cache.get('my_key') 'hello, world!'timeout參數(shù)是可選的,默認(rèn)為CACHES設(shè)置中適當(dāng)后端的timeout參數(shù)(如上所述)。它是值應(yīng)該存儲在緩存中的秒數(shù)。0的timeout將不會緩存該值。
如果對象不存在于緩存中,則cache.get()返回None:
# 等30秒后
>>> cache.get('my_key') None我們建議不要在緩存中存儲文本值None,因?yàn)槟鷮o法區(qū)分您存儲的None值和由返回值表示的緩存未命中None。
cache.get()可以采用default參數(shù)。如果對象不存在于緩存中,則指定返回哪個(gè)值:
>>> cache.get('my_key', 'has expired') 'has expired'要添加鍵(如果它尚不存在),請使用add()方法。它使用與set()相同的參數(shù),但如果指定的鍵已經(jīng)存在,它不會嘗試更新緩存:
>>> cache.set('add_key', 'Initial value') >>> cache.add('add_key', 'New value') >>> cache.get('add_key') 'Initial value'如果你需要知道add()是否在緩存中存儲了一個(gè)值,你可以檢查返回值。如果值存儲,則返回True,否則返回False。
還有一個(gè)get_many()接口,只會命中一次緩存。get_many()返回一個(gè)字典,其中包含您請求的所有實(shí)際存在于緩存中的鍵(并且未過期):
>>> cache.set('a', 1) >>> cache.set('b', 2) >>> cache.set('c', 3) >>> cache.get_many(['a', 'b', 'c']) {'a': 1, 'b': 2, 'c': 3}要更有效地設(shè)置多個(gè)值,請使用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參數(shù)。
您可以使用delete()顯式刪除鍵。這是清除特定對象的緩存的簡單方法:
>>> cache.delete('a')如果您想一次清除一堆鍵,delete_many()可以取得要清除的鍵列表:
>>> cache.delete_many(['a', 'b', 'c'])最后,如果要?jiǎng)h除緩存中的所有鍵,請使用cache.clear()。小心這個(gè);clear()將從緩存中刪除所有,而不僅僅是應(yīng)用程序設(shè)置的鍵。
>>> cache.clear()實(shí)例:
settings.py文件的設(shè)置
# cache配置######################################### CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache','LOCATION': 'unique-snowflake','options': {'MAX_ENTRIES': 10240,}},'memcache': {'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',# 'LOCATION': 'unix:/home/billvsme/memcached.sock','LOCATION': '127.0.0.1:11211','options': {'MAX_ENTRIES': 10240,}}, }views.py代碼開始獲取緩存
# 緩存 try:cache = caches['memcache'] except ImportError as e:cache = caches['default']單個(gè)函數(shù)使用
@api_view(['GET']) @cache_page(60 * 15) def tags_list(request):"""使用裝飾器進(jìn)行相關(guān)操作:param request::return:"""tags = Tag.objects.all()if tags:serializer = TagSerializer(tags, many=True)return Response(serializer.data)else:return Response(status.HTTP_404_NOT_FOUND)?
轉(zhuǎn)載于:https://my.oschina.net/liuyuantao/blog/858036
總結(jié)
以上是生活随笔為你收集整理的Django使用缓存笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bootstrap的两种在input框后
- 下一篇: JavaScript ES2015