J'utilise Memcached comme backend sur mon application Django. Ce code fonctionne bien dans une requête Django normale:
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
Mais cela ne fonctionne pas lorsqu'il est utilisé avec les appels api de Django-rest-framework:
class ProductListAPIView(generics.ListAPIView):
def get_queryset(self):
product_list = Product.objects.all()
return product_list
serializer_class = ProductSerializer
Je suis sur le point d'essayer les extensions DRF qui fournissent une fonctionnalité de mise en cache:
https://github.com/chibisov/drf-extensions
mais le statut de compilation sur github indique actuellement "échec de la compilation".
Mon application est très lue sur les appels api. Existe-t-il un moyen de mettre en cache ces appels?
Je vous remercie.
Ok, donc, pour utiliser la mise en cache pour votre ensemble de requêtes:
class ProductListAPIView(generics.ListAPIView):
def get_queryset(self):
return get_myobj()
serializer_class = ProductSerializer
Cependant, vous souhaiterez probablement définir un délai d’expiration pour le cache (par exemple 60 secondes):
cache.set(cache_key, result, 60)
Si vous souhaitez mettre en cache la vue entière:
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)
Je viens d'implémenter cela à utiliser sur mes sérialiseurs
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
ensuite, je substitue la méthode to_representation sur mes sérialiseurs, afin de mettre en cache la sortie sérialisée par instance.
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)
Essayez cette application Django https://github.com/Onyo/Django-rest-framework-cache
from rest_framework import serializers
# You must import the CachedSerializerMixin and cache_registry
from rest_framework_cache.serializers import CachedSerializerMixin
from rest_framework_cache.registry import cache_registry
from .models import Comment
class CommentSerializer(serializers.ModelSerializer, CachedSerializerMixin):
class Meta:
model = Comment
cache_registry.register(CommentSerializer)