本篇主要介紹如何在在Django REST framework 中使用緩存,以及為什么要使用緩存、有什么優勢。
一、為什么要使用緩存?
在C/S架構中,用戶通過瀏覽器向服務器發送請求,前端會向后端請求數據進行頁面展示。
而對於經常要使用到的數據,而同時這部分數據可能是不經常發生改變的數據,前端會不斷的向后端發送請求,后端再不斷的對數據庫進行查詢。
這樣的話,查詢的過程中會消耗一定的時間,同時也會加大數據庫的性能壓力,那么有沒有更好的辦法呢?
那就是使用緩存。
我們將前端第一次請求響應的數據,放置到緩存中,那么這一定的時間內前端再次進行請求數據時,后端直接將緩存中的數據返回給前端。
這樣做的優點:
- 減少數據庫的查詢次數,提交查詢效率
- 從緩存中讀取數據的速度,要比從數據庫中讀取數據快得多。
二、使用Redis作為緩存對象
為什么使用Redis作為緩存對象呢?
1、Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
2、Redis支持master-slave(主-從)模式應用,可以將數據復制到任意數量的從機中。
3、Redis支持數據持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用。(斷電的情況等。)
4、Redis的讀寫速度異常快。
5、Redis支持設置存儲的過期時間,避免數據存儲的冗余。
如何在Django中將redis設置為默認的緩存?
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1::6379/1",, "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, "session": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1::6379/1",, "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, }
可以在Django的配置文件的CACHES項中指明:
- 緩存后端使用的是何種緩存 -- "BACKEND": "django_redis.cache.RedisCache",這里指明為Redis緩存。
- 指明緩存的地址即Redis的地址 : "LOCATION": "redis://127.0.0.1::6379/1"。
- 選項 -- 指明作為redis客戶端連接redis服務器所使用的類:"CLIENT_CLASS": "django_redis.client.DefaultClient"。
注:我們使用 django-redis 提供了get_redis_connection的方法,通過調用get_redis_connection方法傳遞redis的配置名稱可獲取到redis的連接對象,通過redis連接對象可以執行redis命令。
這里不是我們今天介紹的主題。
三、Django中將數據設置在緩存中
若要將經常被請求的數據且不經常更改的數據存儲在緩存中,可以引入DRF框架的一個擴展:
pip install drf-extensions
其使用方法有以下兩種:
- 直接添加裝飾器
- 使用drf-extensions提供的擴展類
一、直接添加裝飾器:
可以在使用rest_framework_extensions.cache.decorators中的cache_response裝飾器來裝飾返回數據的類視圖的對象方法,如
class CityView(views.APIView): @cache_response() def get(self, request, *args, **kwargs): ...
注:cache_response裝飾器可以接受兩個參數,若不傳,則默認會使用配置文件中的默認配置。
@cache_response(timeout=60*60, cache='default')
- timeout 緩存時間 (對於緩存而言肯定需要設置過期時間)
- cache 緩存使用的Django緩存后端(即CACHES配置中的鍵名稱),上面提到的。
如果在使用cache_response裝飾器時未指明timeout或者cache參數,則會使用配置文件中的默認配置,可以通過如下方法指明:
1 # DRF擴展 2 REST_FRAMEWORK_EXTENSIONS = { 3 # 緩存時間 4 'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60, 5 # 緩存存儲 6 'DEFAULT_USE_CACHE': 'default', 7 }
- DEFAULT_CACHE_RESPONSE_TIMEOUT --- 緩存有效期,單位秒
- DEFAULT_USE_CACHE ---- 緩存的存儲方式,與配置文件中的
CACHES
的鍵對應
注:cache_response裝飾器既可以裝飾在類視圖中的get方法上,也可以裝飾在REST framework擴展類提供的list或retrieve方法上。使用cache_response裝飾器無需使用method_decorator進行轉換。
二、使用drf-extensions提供的擴展類
以下三個擴展類都是在 rest_framework_extensions.cache.mixins
中。
-
ListCacheResponseMixin
用於緩存返回列表數據的視圖,與ListModelMixin擴展類配合使用,實際是為list方法添加了cache_response裝飾器
-
RetrieveCacheResponseMixin
用於緩存返回單一數據的視圖,與RetrieveModelMixin擴展類配合使用,實際是為retrieve方法添加了cache_response裝飾器
-
CacheResponseMixin
為視圖集同時補充List和Retrieve兩種緩存,與ListModelMixin和RetrieveModelMixin一起配合使用。
例如:
from rest_framework_extensions.cache.mixins import CacheResponseMixin class AreasViewSet(CacheResponseMixin, ReadOnlyModelViewSet): '''給list/retrieve視圖返回的數據添加到緩存''' pass class AddressViewSet(ListCacheResponseMixin,viewsets.ViewSet): '''給list視圖添加cache_response,即用於返回的列表數據 添加到緩存''' def list(self, request): ... def retrieve(self, request, pk=None): ...
over~~~,本篇主要提供一個思想,若常用的數據且不常發生變更的數據,為了減少數據庫的查詢次數和提升查詢速度 可以將第一次響應的數據添加到緩存中,而對於這類數據作為緩存對象的最好選擇便是 --- Redis。