溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Django的緩存(2)

發(fā)布時(shí)間:2020-07-01 05:49:18 來(lái)源:網(wǎng)絡(luò) 閱讀:1089 作者:孤雁不獨(dú)飛 欄目:開(kāi)發(fā)技術(shù)

  前面介紹了緩存的一些簡(jiǎn)單知識(shí)以及在Django中如何設(shè)置參數(shù)來(lái)配置這些緩存,現(xiàn)在講講在django中如何使用緩存。

(1)站點(diǎn)級(jí)緩存

  站點(diǎn)級(jí)緩存指使用緩存緩存整個(gè)網(wǎng)站,需要添加兩個(gè)中間件到MIDDLEWRAE_CLASSES:django.middleware.UpdateCacheMiddleware和django.middleware.cache.FetchFromCacheMiddleware,注意的是,UpdateCache中間件一定要放在第一位,F(xiàn)etch中間件必須放最后(因?yàn)橹虚g件的順序決定著運(yùn)行的順序)見(jiàn)下面示例:

MIDDLEWARE_CLASSES = (
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
)

除了上面的設(shè)置外還需要在setting文件中增加以下設(shè)置:

CACHE_MIDDLEWARE_ALIAS:用來(lái)存儲(chǔ)的緩存別名

CACHE_MIDDLEWARE_SECONDS:每個(gè)頁(yè)面應(yīng)該被緩存的秒數(shù)

CACHE_MIDDLEWARE_KEY_PREFIX:關(guān)鍵的前綴,當(dāng)多個(gè)站點(diǎn)使用同一個(gè)配置的時(shí)候,這個(gè)可以設(shè)置可以避免發(fā)生沖突;如果你不在乎的話, 你可以是用一個(gè)空字符串,建議你別這樣做

如果請(qǐng)求或者響應(yīng)的頭部允許的時(shí)候,緩存中間件會(huì)緩存那些200的get或者h(yuǎn)ead的相應(yīng)頁(yè)面。同一個(gè)url但是不同查詢(xún)參數(shù)會(huì)被認(rèn)為是不同的相應(yīng)從而被分別緩存。

如果你設(shè)置了CACHE_MIDDLEWARE_ANONYMOUS_ONLY為真,那么只有匿名的請(qǐng)求會(huì)被緩存,這是一個(gè)禁用緩存非匿名用戶(hù)頁(yè)面的最簡(jiǎn)單的做法,注意確保已經(jīng)啟用了認(rèn)證中間件。

緩存中間件希望一個(gè)head請(qǐng)求可以被 一個(gè)有相同響應(yīng)頭部的get請(qǐng)求的響應(yīng) 響應(yīng),因?yàn)檫@樣的話,緩存中間件可以直接用一個(gè)get響應(yīng)返回給一個(gè)head請(qǐng)求。

另外,緩存中間件會(huì)自動(dòng)的設(shè)置少量的頭部信息給每一個(gè)HttpResponse:

當(dāng)一個(gè)新鮮的頁(yè)面被請(qǐng)求的時(shí)候,會(huì)用當(dāng)前時(shí)間打上一個(gè)Last_Modified的頭部

會(huì)用當(dāng)前時(shí)間加上CACHE_MIDDLEWARE_SECONDS的值設(shè)置給Expires頭部

用CACHE_MIDDLEWARE_SECONDS的值給Cache-Control頭部去設(shè)置一個(gè)頁(yè)面的最大年齡(前提是視圖函數(shù)沒(méi)有設(shè)置該項(xiàng))


(2)單個(gè)view緩存

django.views.decorators.cache.cache_page()

  更加輕巧的緩存框架使用方法是對(duì)單個(gè)有效視圖的輸出進(jìn)行緩存。 django.views.decorators.cache 定義了一個(gè)自動(dòng)緩存視圖響應(yīng)的 cache_page裝飾器,使用非常簡(jiǎn)單:

from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
    ....

cache_page只接受一個(gè)參數(shù)和兩個(gè)關(guān)鍵字參數(shù),

timeout是緩存時(shí)間,以秒為單位

cache:指定使用你的CACHES設(shè)置中的哪一個(gè)緩存后端

key_prefix:指定緩存前綴,可以覆蓋在配置文件中CACHE_MIDDLEWARE_KEY_PREFIX的值

和站點(diǎn)緩存一樣,視圖緩存與 URL 無(wú)關(guān)。如果多個(gè) URL 指向同一視圖,每個(gè)URL將會(huì)分別緩存。  繼續(xù) my_view范例,如果 URLconf 如下所示:

urlpatterns = [
    url(r'^foo/([0-9]{1,2})/$', my_view),
]

發(fā)送到 /foo/1/ and /foo/23/ 會(huì)被分別緩存。但是一旦一個(gè)明確的 URL (e.g., /foo/23/) 已經(jīng)被請(qǐng)求過(guò)了, 之后再度發(fā)出的指向該 URL 的請(qǐng)求將使用緩存


(3)在url配置文件中使用緩存裝飾器

和上面的類(lèi)似,裝飾器的位置發(fā)生了變化

from django.views.decorators.cache import cache_page

urlpatterns = ('',
    (r'^foo/(\d{1,2})/$', cache_page(60 * 15)(my_view)),
)

(4)模板片段緩存 

  如果想對(duì)緩存進(jìn)行更多的控制,可以使用 cache模板標(biāo)簽來(lái)緩存模板的一個(gè)片段。 要讓模板處理這個(gè)標(biāo)簽,把{% load cache %} 放在緩存片段的上面。

  標(biāo)簽{% cache %}將按給定的時(shí)間緩存包含塊中的內(nèi)容。它最少需要兩個(gè)參數(shù):緩存時(shí)間(以秒為單位);給緩存片段起的名稱(chēng)。該名稱(chēng)將不使能用變量。

{% load cache %}
{% cache 500 sidebar %}
    .. sidebar ..
{% endcache %}

sidebar就是要緩存的片段代碼,緩存的是這個(gè)片段。當(dāng)然也可以可以依據(jù)這個(gè)片段內(nèi)的動(dòng)態(tài)內(nèi)容緩存多個(gè)版本。如上面例子中,可以給站點(diǎn)的每個(gè)用戶(hù)生成不同版本的sidebar緩存。只需要給 {% cache %}標(biāo)簽再傳遞一個(gè)參數(shù)來(lái)標(biāo)識(shí)區(qū)分這個(gè)緩存片段。

{% load cache %}
{% cache 500 sidebar request.user.username %}
    .. sidebar for logged in user ..
{% endcache %}

指定一個(gè)以上的參數(shù)來(lái)識(shí)別片段是一個(gè)很好的選擇,簡(jiǎn)單的盡可能的傳遞需要的參數(shù)到{% cache %}。


(5)底層的緩存API

  有時(shí)候不想緩存一個(gè)頁(yè)面,甚至不想某個(gè)頁(yè)面的一部分,只是想緩存某個(gè)數(shù)據(jù)庫(kù)檢索的結(jié)果,django提供了底層次的API,可以是用這些API來(lái)緩存任何粒度的數(shù)據(jù),模型對(duì)象的字符串,字典,列表等等。(實(shí)際上我就是用這種方法)

  可以通過(guò)類(lèi)字典對(duì)象django.core.cache.caches.訪問(wèn)配置在CACHES 設(shè)置中的字典類(lèi)對(duì)象。對(duì)同一線程相同的別名重復(fù)請(qǐng)求將返回相同的對(duì)象。

>>> from django.core.cache import caches
>>> cache1 = caches['myalias']
>>> cache2 = caches['myalias']
>>> cache1 is cache2

True

如果key不存在,就會(huì)引發(fā)一個(gè) InvalidCacheBackendError。

  如果想了解所有的API,建議去看django\core\cache\backends目錄下的cache.py文件,這里僅僅列舉一些簡(jiǎn)單的用法

下面是如何導(dǎo)入這個(gè) API : 

from django.core.cache import cache

基本的接口是 set(key, value, timeout_seconds) 和 get(key) : 

‘hello, world!’

timeout_seconds 參數(shù)是可選的, 并且默認(rèn)為前面講過(guò)的 CACHE_BACKEND 設(shè)置中的 timeout 參數(shù). 

如果對(duì)象在緩存中不存在, 或者緩存后端是不可達(dá)的, cache.get() 返回 None : 

# Wait 30 seconds for ‘my_key’ to expire…

>>> cache.get(’my_key’)

None

>>> cache.get(’some_unset_key’)

None

不建議在緩存中保存 None 常量,因?yàn)槟銓o(wú)法區(qū)分所保存的 None 變量及由返回值 None 所標(biāo)識(shí)的緩存未中。 

cache.get() 接受一個(gè) 缺省 參數(shù)。其指定了當(dāng)緩存中不存在該對(duì)象時(shí)所返回的值: 

>>> cache.get(’my_key’, ‘has expired’)

‘has expired’

要想一次獲取多個(gè)緩存值,可以使用 cache.get_many() 。如果可能的話,對(duì)于給定的緩存后端, get_many() 將只訪問(wèn)緩存一次,而不是對(duì)每個(gè)緩存鍵值都進(jìn)行一次訪問(wèn)。 get_many() 所返回的字典包括了你所請(qǐng)求的存在于緩存中且未超時(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}

如果某個(gè)緩存關(guān)鍵字不存在或者已超時(shí), 它將不會(huì)被包含在字典中。下面是范例的延續(xù): 

>>> cache.get_many(['a', 'b', 'c', 'd'])

{’a': 1, ‘b’: 2, ‘c’: 3}

最后,你可以用 cache.delete() 顯式地刪除關(guān)鍵字。這是在緩存中清除特定對(duì)象的簡(jiǎn)單途徑。 

>>> cache.delete(’a')

cache.delete() 沒(méi)有返回值, 不管給定的緩存關(guān)鍵字對(duì)應(yīng)的值存在與否, 它都將以同樣方式工作。




向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI