本篇主要介绍如何在在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。