DRF缓存

对于现在的动态网站来讲,所有的界面展示都是通过客户端请求服务端,服务端再去请求数据库,然后将请求到的数据渲染后返回给客户端。用户每次访问页面都需要去请求数据库,如果同时有多个人访问的话,对于我们的数据库的压力是相当大的。

所以我们会想,对于不是经常变更的数据,或者不需要实时更新展示的数据,我们可以将数据存放在缓存中,用户下次需要数据的时候,服务端直接从缓存中拿到数据返回给用户即可,不需要每次都去数据库查询,这样会大大降低数据库的压力,提升用户访问速度。

Django提供了多种缓存方法,具体可以参考:https://docs.djangoproject.com/zh-hans/2.1/topics/cache/

 

下面我们来看看DRF缓存,它对Django的缓存进行了一层封装,使我们用起来更加方便

Django REST Framework中使用缓存,可以使用GitHub上提供的drf-extensions扩展来实现

GitHub地址:https://github.com/chibisov/drf-extensions

参考文档:http://chibisov.github.io/drf-extensions/docs/#caching

drf-extensions 缓存工作原理:

  收到用户请求时,会根据请求对应的 view_instance, view_method, request, args, kwargs 等生成一个key,然后通过这个key去内存中查找是否有对应的value,如果有value,将其封装成对应的response返回给客户端

  如果通过key没有找到对应的value,则去执行我们的视图函数对应的方法,并将结果作为key值保存在内存中,以便下次使用。

    DRF缓存

1、安装drf-extensions:pip install drf-extensions

2、使用方法:

  首先需要安装 drf-extensions 库:pip install drf-extensions

  1)使用装饰器方式

    @cache_response

     它适用于继承了rest_framework.views.APIView的类,且需要返回一个rest_framework.response.Response的实例

    用法如下:   

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framwork_extensions.cache.decorator import cache_response
class GoodListView(APIView):
    @cache_response()
    def get(self, request, format=None):
        goods = Goods.objects.all()[:10]
        goods_serializer = GoodListSerializer1(goods, many=True)
        return Response(goods_serializer.data)

     第一次访问goods接口,看到使用的时间是1.44s

    DRF缓存

 

    然后我们再次刷新界面,看到goods接口只是用了259ms

    DRF缓存

    @cache_response()接受4个参数

     DRF缓存

    a)timeout:指定过期时间,单位为秒,即缓存有效期时间。默认为None,即永久缓存,我们也可以在设置文件中修改此参数

      REST_FRAMEWORK_EXTENSIONS = {

        'DEFAULT_CACHE_RESPONSE_TIMEOUT':60*15  # 即指定有效期为15分钟

      }

    b)key_func:指定缓存键,默认情况下,每个来自@cache_response装饰器的缓存数据都由key存储,使用DefaultKeyConstructor计算

    c)cache:指定装饰器在缓存结果时使用特定的缓存,一般情况下,我们会直接使用默认的default 缓存

    d)cache_errors:默认情况下,每个response都会被缓存,包括错误,所以如果我们第一次请求的时候中间出现错误,那么在缓存有效期内,每一次的请求都将会直接将之前缓存的错误信息返回给我们。

      我们可以通过修改cache_errors的值为False来改变这种行为。

      REST_FRAMEWORK_EXTENSIONS = {

        'DEFAULT_CACHE_RESPONSE_TIMEOUT':60*15,  # 即指定有效期为15分钟

        ‘DEFAULT_CACHE_ERRORS’:False

      }

   2)使用CacheResponseMixin

    用于缓存标准视图retrieve和list方法。和viewset搭配使用。

    CacheResponseMixin本质上也是使用@Cache_response()装饰器实现,在它的基础上进行了进一步封装,使得使用更加便捷

    mixin的示例使用方法:

from rest_framework_extensions.cache.mixins import CacheResponseMixin
class GoodListView3(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = Goods.objects.all().order_by("add_time")
    serializer_class = GoodListSerializer1
    pagination_class = GoodPageView

    只需要将CacheResponseMixin加入到我们的试图类函数第一个继承类位置即可。

    DRF缓存

    查看rest_framework_extensions.cache.mixins,可以看到,它下面提供了四个类:

    BaseCacheResponseMixin:公共类,只是指定了默认的缓存键功能

    ListCacheResponseMixin:继承自BaseCacheResponseMixin,针对list方法缓存

    RetrieveCacheResponseMixin:针对retrieve方法缓存

    CacheResponseMixin:继承了ListCacheResponseMixin和RetrieveCacheResponseMixin,即既可以对list也可以针对retrieve方法进行缓存。

 

上一篇:【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)


下一篇:rest_framework_extensions实现缓存