如何缓存 Django Rest Framework API 调用?
How to cache Django Rest Framework API calls?
我使用 Memcached 作为我的 Django 应用程序的后端。此代码在正常的 Django 查询中工作正常:
def get_myobj():
cache_key = 'mykey'
result = cache.get(cache_key, None)
if not result:
result = Product.objects.all().filter(draft=False)
cache.set(cache_key, result)
return result
但是当与 django-rest-framework api 调用时它不起作用:
class ProductListAPIView(generics.ListAPIView):
def get_queryset(self):
product_list = Product.objects.all()
return product_list
serializer_class = ProductSerializer
我即将尝试提供缓存功能的 DRF 扩展:
https://github.com/chibisov/drf-extensions
但 github 上的构建状态目前显示 "build failing"。
我的应用在 api 调用时读取量很大。有没有办法缓存这些调用?
谢谢。
好的,所以,为了对您的查询集使用缓存:
class ProductListAPIView(generics.ListAPIView):
def get_queryset(self):
return get_myobj()
serializer_class = ProductSerializer
不过您可能希望在缓存集上设置超时(例如 60 秒):
cache.set(cache_key, result, 60)
如果要缓存整个视图:
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
class ProductListAPIView(generics.ListAPIView):
serializer_class = ProductSerializer
@method_decorator(cache_page(60))
def dispatch(self, *args, **kwargs):
return super(ProductListAPIView, self).dispatch(*args, **kwargs)
我刚刚实现了它以在我的序列化程序上使用
def cache_me(cache):
def true_decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
instance = args[1]
cache_key = '%s.%s' % (instance.facility, instance.id)
logger.debug('%s cache_key: %s' % (cache, cache_key))
try:
data = caches[cache].get(cache_key)
if data is not None:
return data
except:
pass
logger.info('did not cache')
data = f(*args, **kwargs)
try:
caches[cache].set(cache_key, data)
except:
pass
return data
return wrapper
return true_decorator
然后我在我的序列化器上重写 to_representation 方法,因此它缓存每个实例的序列化输出。
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
exclude = ('is_deleted', 'facility',)
@cache_me('mymodel')
def to_representation(self, instance):
return super(MyModelSerializer, self).to_representation(instance)
我使用 Memcached 作为我的 Django 应用程序的后端。此代码在正常的 Django 查询中工作正常:
def get_myobj():
cache_key = 'mykey'
result = cache.get(cache_key, None)
if not result:
result = Product.objects.all().filter(draft=False)
cache.set(cache_key, result)
return result
但是当与 django-rest-framework api 调用时它不起作用:
class ProductListAPIView(generics.ListAPIView):
def get_queryset(self):
product_list = Product.objects.all()
return product_list
serializer_class = ProductSerializer
我即将尝试提供缓存功能的 DRF 扩展:
https://github.com/chibisov/drf-extensions
但 github 上的构建状态目前显示 "build failing"。
我的应用在 api 调用时读取量很大。有没有办法缓存这些调用?
谢谢。
好的,所以,为了对您的查询集使用缓存:
class ProductListAPIView(generics.ListAPIView):
def get_queryset(self):
return get_myobj()
serializer_class = ProductSerializer
不过您可能希望在缓存集上设置超时(例如 60 秒):
cache.set(cache_key, result, 60)
如果要缓存整个视图:
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
class ProductListAPIView(generics.ListAPIView):
serializer_class = ProductSerializer
@method_decorator(cache_page(60))
def dispatch(self, *args, **kwargs):
return super(ProductListAPIView, self).dispatch(*args, **kwargs)
我刚刚实现了它以在我的序列化程序上使用
def cache_me(cache):
def true_decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
instance = args[1]
cache_key = '%s.%s' % (instance.facility, instance.id)
logger.debug('%s cache_key: %s' % (cache, cache_key))
try:
data = caches[cache].get(cache_key)
if data is not None:
return data
except:
pass
logger.info('did not cache')
data = f(*args, **kwargs)
try:
caches[cache].set(cache_key, data)
except:
pass
return data
return wrapper
return true_decorator
然后我在我的序列化器上重写 to_representation 方法,因此它缓存每个实例的序列化输出。
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
exclude = ('is_deleted', 'facility',)
@cache_me('mymodel')
def to_representation(self, instance):
return super(MyModelSerializer, self).to_representation(instance)