Django REST Framework: 使用cach_page和drf-extensions进行缓存

对于经常被查询使用而且不怎么变化的数据, 建议对Django REST Framework(DRF)的响应数据进行缓存, 这样可以避免重复数据库查询, 大大加快响应时间。DRF支持两种数据缓存方式: 1. Django的原生cache_page装饰器; 2. drf-extensions这个第三方库。

方法1. 原生cache_page装饰器

 

使用Django提供的method_decorator装饰器,可以将普通装饰器比如cache_page应用于类视图里。cache_page可以指定缓存时间(单位秒)。

from django.utils.decorators import method_decoratorfrom django.views.decorators.cache import cache_pagefrom django.views.decorators.vary import vary_on_cookie, vary_on_headers
from rest_framework.response import Responsefrom rest_framework.views import APIViewfrom rest_framework import viewsets

class UserViewSet(viewsets.ViewSet): # With cookie: cache requested url for each user for 2 hours @method_decorator(cache_page(60*60*2)) @method_decorator(vary_on_cookie) def list(self, request, format=None): content = { 'user_feed': request.user.get_user_feed() } return Response(content)

class ProfileView(APIView): # With auth: cache requested url for each user for 2 hours @method_decorator(cache_page(60*60*2)) @method_decorator(vary_on_headers("Authorization",)) def get(self, request, format=None): content = { 'user_feed': request.user.get_user_feed() } return Response(content)

class PostView(APIView):    # 缓存特定请求url地址的数据 @method_decorator(cache_page(60*60*2)) def get(self, request, format=None): content = { 'title': 'Post title', 'body': 'Post content' } return Response(content)

注意:cache_page只能缓存GET和HEAD请求,并返回200的状态码。

 

方法2. 使用drf-extensions第三方库

 

1. pip安装

pip install drf-extensions

2. 直接添加cache_response装饰器

drf-extensions提供的cache_response装饰器可以直接应用于get方法上,而无需使用method_decorator进行转换。

from rest_framework_extensions.cache.decorators import cache_response
class UserView(views.APIView): @cache_response() def get(self, request, *args, **kwargs): ...

cache_response装饰器可以接收两个参数, 一个为缓存时间,一个为默认缓存后端名字,如下所示:

@cache_response(timeout=60*60, cache='default')

如果不设置参数,可以在settings.py进行默认配置:

# settings.py# DRF扩展REST_FRAMEWORK_EXTENSIONS = {    # 默认缓存时间    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60,    # 缓存存储    'DEFAULT_USE_CACHE': 'default',}

注意,cache_response装饰器既可以装饰在类视图中的get方法上,也可以装饰在REST framework扩展类提供的list或retrieve方法上。

3. 使用drf-extensions提供的扩展类
drf-extensions还提供了如下3个常用的扩展Mixin类,位于rest_framework_extensions.cache.mixins中。

 

ListCacheResponseMixin

用于缓存返回列表数据的视图,与ListModelMixin扩展类配合使用,实际是为list方法添加了cache_response装饰器

 

RetrieveCacheResponseMixin

用于缓存返回单一数据的视图,与RetrieveModelMixin扩展类配合使用,实际是为retrieve方法添加了cache_response装饰器

 

CacheResponseMixin

为视图集同时补充List和Retrieve两种缓存,与ListModelMixin和RetrieveModelMixin一起配合使用。

 

最常用的是CacheResponseMixin,它对单个对象或对象列表都进行缓存,使用示例如下所示:

 from myapps.serializers import UserSerializer from rest_framework_extensions.cache.mixins import CacheResponseMixin
class UserViewSet(CacheResponseMixin, viewsets.ModelViewSet): serializer_class = UserSerializer

 

小结

Django REST Framework(DRF)提供了2种对经常查询使用却又不怎么变化的响应数据进行缓存的方法: 1. Django的原生cache_page装饰器; 2. drf-extensions这个第三方库。个人优先推荐drf-extensions提供的CacheResponseMixin这个Mixin类。

 

posted @ 2021-08-13 10:12  侃豺小哥  阅读(212)  评论(0编辑  收藏  举报