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