應用環境 django4.2.3 ,python3.10?
由于對于服務而言,有些數據查詢起來比較費時,所以,對于有些數據,我們需要將其緩存。
最近做了一個服務,用的時 DRF 的架構,剛好涉及緩存,特此記錄。
DRF的緩存,和django自帶的緩存有個比較大的區別:django自帶的緩存,一旦將數據緩存,那么數據源一旦發生變化,那么我們從緩存中取到的內容,就是老的內容,并不是最新的內容。但是? DRF 的緩存,卻是會自動更新的,比如,已經緩存了數據庫的一些數據,這時,數據庫的這些數據被更新了,那么,DRF 也將會對已經緩存了的數據自動進行更新。
然后,看下大致的用法:
先下載包:
pip3?install drf-extensions
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from machines.models import Repository
from rest_framework_extensions.cache.decorators import cache_response
from machines.api.serializers import RepositorySerializersclass RepoInfoViewSet(GenericAPIView):queryset = Repository.objects.all()serializer_class = RepositorySerializersdef _get_repositories(self, state, servicename, service_port):base = Repository.objectsreturn Response(self.get_serializer(instance=base.all(),many=True).data)@staticmethoddef set_cache_key(request, *args, **kwargs):return request.path@cache_response(timeout=300, cache='default', key_func='set_cache_key')def get(self, request, state=None, servicename=None, service_port=None):return self._get_repositories(state, servicename, service_port)
大概說下,cache_response 方法就可以直接搞緩存,它里面那幾個參數,
timeout:指緩存的過期時間。
cache:指在要用的緩存對象,它的值,就是在 settings.py 中 CACHES 參數中的配置的 key。
key_func:這里涉及一個問題,通常情況下,緩存的時候都是這么干的:cache.set("key", "value", 60) , 就是說,緩存對象,存一個key,以及要緩存的內容value,和緩存的過期時間。那么,一般來說,這個key,是不需要我們直接提供的,django會自動分配一個獨一無二的key給它,在 DRF中,用的是這個對象:
?它將為要緩存的對象,構建一個獨一無二的key,之所以介紹這么一個東西,是因為,這個key,將涉及清除緩存的問題,如果是清除所有緩存,那就無所謂,不存在問題,直接 clear() 完事,但是如果涉及定點清除,那么問題就來了,我們根本就不知道我們要清除的數據它的key是多少,那么就沒法清除具體的某個緩存了。所以,這個時候,就需要用到 key_func 這個參數,我們需要構建一個制作key的函數,讓其返回一個字符串,來成為我們要緩存對象的key,這樣以來,我們就知道了緩存對象的key,后續如果需要清除掉這個緩存就可以直接 cache.delete(key) 來清除它了。
我的這個示例中自己構造了set_cache_key函數來制作我需要的緩存key,它的執行結果是這樣的:
先訪問一次服務,讓其產生緩存
?然后,訪問清除緩存動作:
對了,補充一句,這塊用的cache是從這來的:from django.core.cache import cache
可以看到,緩存對象的 key 確實就是我自己定義的 request.path。
當然,我這里用的依舊是cache.clear(),因為我這里的業務邏輯,只有一處緩存,那么清除的話,一把全清也不影響,但是,如果客戶要求清除某些特定的緩存的話那就可以使用 cache.delete()方法了,比如:
連著弄兩次,第二次就會出問題,因為第一次就已經刪除了key,自然就沒有這個緩存了,再刪就會失敗。
另外,看一個文件緩存的配置:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache','LOCATION': '/tmp/django_cache','TIMEOUT': 60,'OPTIONS': {'MAX_ENTRIES': 1000}}
}
settings.py中可以有其他的緩存配置,比如使用redis....