Django緩存Cache使用詳解
緩存(Cache)對于創(chuàng)建一個高性能的網(wǎng)站和提升用戶體驗來說是非常重要的,然而對我們這種只用得起拼多多的碼農(nóng)而言最重要的是學(xué)會如何使用緩存。今天我們就來看看緩存Cache應(yīng)用場景及工作原理吧,并詳細介紹如何在Django中設(shè)置Cache并使用它們。
什么是緩存Cache
緩存是一類可以更快的讀取數(shù)據(jù)的介質(zhì)統(tǒng)稱,也指其它可以加快數(shù)據(jù)讀取的存儲方式。一般用來存儲臨時數(shù)據(jù),常用介質(zhì)的是讀取速度很快的內(nèi)存。一般來說從數(shù)據(jù)庫多次把所需要的數(shù)據(jù)提取出來,要比從內(nèi)存或者硬盤等一次讀出來付出的成本大很多。對于中大型網(wǎng)站而言,使用緩存減少對數(shù)據(jù)庫的訪問次數(shù)是提升網(wǎng)站性能的關(guān)鍵之一。
為什么要使用緩存Cache
在Django中,當用戶請求到達視圖后,視圖會先從數(shù)據(jù)庫提取數(shù)據(jù)放到模板中進行動態(tài)渲染,渲染后的結(jié)果就是用戶看到的網(wǎng)頁。如果用戶每次請求都從數(shù)據(jù)庫提取數(shù)據(jù)并渲染,將極大降低性能,不僅服務(wù)器壓力大,而且客戶端也無法即時獲得響應(yīng)。如果能將渲染后的結(jié)果放到速度更快的緩存中,每次有請求過來,先檢查緩存中是否有對應(yīng)的資源,如果有,直接從緩存中取出來返回響應(yīng),節(jié)省取數(shù)據(jù)和渲染的時間,不僅能大大提高系統(tǒng)性能,還能提高用戶體驗。
我們來看一個實際的博客例子。每次當我們訪問首頁時,下面視圖都會從數(shù)據(jù)庫中提取文章列表,并渲染的模板里去。大多數(shù)情況下,我們的博客不會更新得那么頻繁,所以文章列表是不變的。這樣用戶在一定時間內(nèi)多次訪問首頁時都從數(shù)據(jù)庫重新讀取同樣的數(shù)據(jù)是一種很大的浪費。
from django.shortcuts import render def index(request): # 讀取數(shù)據(jù)庫等并渲染到網(wǎng)頁 article_list = Article.objects.all() return render(request, 'index.html', {'article_list': article_list})
使用緩存Cache就可以幫我們解決這個問題。當用戶首次訪問博客首頁時,我們從數(shù)據(jù)庫中提取文章列表,并將其存儲到緩存里(常用的是內(nèi)存,這取決于你的設(shè)置)。當用戶在單位時間內(nèi)再次訪問首頁時, Django先檢查緩存是否過期(本例是15分鐘), 再檢查緩存里文章列表資源是否存在,如果存在,直接從緩存中讀取數(shù)據(jù), 并渲染模板。
from django.shortcuts import render from django.views.decorators.cache import cache_page @cache_page(60 * 15) # 秒數(shù),這里指緩存 15 分鐘 def index(request): article_list = Article.objects.all() return render(request, 'index.html', {'article_list': article_list})
注意: 在Django中使用緩存前,我們必需先做必要的設(shè)置。
緩存Cache的應(yīng)用場景
緩存主要適用于對頁面實時性要求不高的頁面。存放在緩存的數(shù)據(jù),通常是頻繁訪問的,而不會經(jīng)常修改的數(shù)據(jù)。我們來舉幾個應(yīng)用例子:
- 博客文章。假設(shè)用戶一天更新一篇文章,那么可以為博客設(shè)置1天的緩存,一天后會刷新。
- 購物網(wǎng)站。商品的描述信息幾乎不會變化,而商品的購買數(shù)量需要根據(jù)用戶情況實時更新。我們可以只選擇緩存商品描述信息。
- 緩存網(wǎng)頁片段。比如緩存網(wǎng)頁導(dǎo)航菜單和腳部(Footer)。
Django緩存設(shè)置
Django中提供了多種緩存方式,如果要使用緩存,需要先在settings.py中進行配置,然后應(yīng)用。根據(jù)緩存介質(zhì)的不同,你需要設(shè)置不同的緩存后臺Backend。
Memcached緩存
Memcached是基于內(nèi)存的緩存,Django原生支持的最快最有效的緩存系統(tǒng)。對于大多數(shù)場景,我們推薦使用Memcached,數(shù)據(jù)緩存在服務(wù)器端。使用前需要通過pip安裝memcached的插件python-memcached和pylibmc,可以同時支持多個服務(wù)器上面的memcached。
下面是使用pyhon-memcached的設(shè)置。
# localhost CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } } # unix soket CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': 'unix:/tmp/memcached.sock', } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': [ '172.19.26.240:11211', '172.19.26.242:11211', ] # 我們也可以給緩存機器加權(quán)重,權(quán)重高的承擔更多的請求,如下 'LOCATION': [ ('172.19.26.240:11211',5), ('172.19.26.242:11211',1), ] } }
數(shù)據(jù)庫緩存
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': 'my_cache_table', }
文件系統(tǒng)緩存
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 'LOCATION': '/var/tmp/django_cache',#這個是文件夾的路徑 #'LOCATION': 'c:\foo\bar',#windows下的示例 } }
本地內(nèi)存緩存
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'unique-snowflake' } }
Django代碼中如何使用Cache
當你做好Cache的設(shè)置后,在代碼中你可以有三種方式使用Cache。
- 在視圖View中使用
- 在路由URLConf中使用
- 在模板中使用
在視圖View中使用cache
from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ...
在路由URLConf中使用cache
這是小編我更喜歡的方式,這樣你就不用修改負責邏輯部分的view了。
from django.views.decorators.cache import cache_page urlpatterns = [ path('foo/<int:code>/', cache_page(60 * 15)(my_view)), ]
在模板中使用cache
{% load cache %} {% cache 500 sidebar request.user.username %} .. sidebar for logged in user .. {% endcache %}
對于大部分碼農(nóng)而言,我們只需要懂得如何在django中使用cache即可,而不需要詳細了解django后臺工作原理,比如Django是如何將數(shù)據(jù)存儲到選定介質(zhì)的以及django是如何判斷緩存是否已經(jīng)過期的。
Django中使用Cache的高級技巧
下面我來介紹下Django中使用cache的一些高級技巧。
使用cache_control
通常用戶將會面對兩種緩存: 他或她自己的瀏覽器緩存(私有緩存)以及他或她的提供者緩存(公共緩存)。 公共緩存由多個用戶使用,而受其它人的控制。 這就產(chǎn)生了你不想遇到的敏感數(shù)據(jù)的問題,比如說你的銀行賬號被存儲在公眾緩存中。 因此,Web 應(yīng)用程序需要以某種方式告訴緩存那些數(shù)據(jù)是私有的,哪些是公共的。
解決方案是標示出某個頁面緩存應(yīng)當是私有的。 要在 Django 中完成此項工作,可使用 cache_control 視圖修飾器:
from django.views.decorators.cache import cache_control @cache_control(private=True) def my_view(request): # ...
該修飾器負責在后臺發(fā)送相應(yīng)的 HTTP 頭部。
還有一些其他方法可以控制緩存參數(shù)。 例如, HTTP 允許應(yīng)用程序執(zhí)行如下操作:
- 定義頁面可以被緩存的最大時間。
- 指定某個緩存是否總是檢查較新版本,僅當無更新時才傳遞所緩存內(nèi)容。
在 Django 中,可使用 cache_control 視圖修飾器指定這些緩存參數(shù)。 在下例中, cache_control 告訴緩存對每次訪問都重新驗證緩存并在最長 3600 秒內(nèi)保存所緩存版本。
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
使用vary_on_headers
缺省情況下,Django 的緩存系統(tǒng)使用所請求的路徑(如blog/article/1)來創(chuàng)建其緩存鍵。這意味著不同用戶請求同樣路徑都會得到同樣的緩存版本,不考慮客戶端user-agent, cookie和語言配置的不同, 除非你使用Vary頭部通知緩存機制需要考慮請求頭里的cookie和語言的不同。
要在 Django 完成這項工作,可使用便利的 vary_on_headers 視圖裝飾器。例如下面代碼告訴Django讀取緩存數(shù)據(jù)時需要同時考慮User-Agent和Cookie的不同。
from django.views.decorators.vary import vary_on_headers @vary_on_headers('User-Agent', 'Cookie') def my_view(request): ...
使用never_cache禁用緩存
如果你想用頭部完全禁掉緩存, 你可以使用django.views.decorators.cache.never_cache裝飾器。如果你不在視圖中使用緩存,服務(wù)器端是肯定不會緩存的,然而用戶的客戶端如瀏覽器還是會緩存一些數(shù)據(jù),這時你可以使用never_cache禁用掉客戶端的緩存。
from django.views.decorators.cache import never_cache @never_cache def myview(request): # ...
到此這篇關(guān)于Django緩存Cache使用詳解的文章就介紹到這了,更多相關(guān)Django緩存Cache內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python基于pygame實現(xiàn)圖片代替鼠標移動效果
這篇文章主要介紹了Python基于pygame實現(xiàn)圖片代替鼠標移動效果,可實現(xiàn)將鼠標箭頭轉(zhuǎn)換成圖形的功能,涉及pygame圖形操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11python實現(xiàn)用類讀取文件數(shù)據(jù)并計算矩形面積
今天小編就為大家分享一篇python實現(xiàn)用類讀取文件數(shù)據(jù)并計算矩形面積,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01Python range、enumerate和zip函數(shù)用法詳解
這篇文章主要介紹了Python range、enumerate和zip函數(shù)用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下2019-09-09關(guān)于Python使用logging庫進行有效日志管理的方法詳解
在開發(fā)大型軟件或處理復(fù)雜問題時,我們經(jīng)常需要一種方法來記錄和跟蹤程序的運行狀態(tài),Python 提供了一個名為 logging 的標準庫,可以幫助我們更好地完成這項任務(wù),在這篇文章中,我們將介紹如何使用 Python 的 logging 庫進行日志記錄2023-06-06解決python報錯:AttributeError:?'ImageDraw'?object?h
這篇文章主要給大家介紹了關(guān)于解決python報錯:AttributeError:?'ImageDraw'?object?has?no?attribute?'textbbox'的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2024-01-01Python3.9.1中使用split()的處理方法(推薦)
這篇文章主要介紹了Python3.9.1中使用split()的處理方法(推薦),本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02