How to cache Django Rest Framework API calls?

Kitti Wateesatogkij picture Kitti Wateesatogkij · Jul 12, 2016 · Viewed 25.8k times · Source

I'm using Memcached as backend to my django app. This code works fine in normal django query:

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

But it doesn't work when used with django-rest-framework api calls:

class ProductListAPIView(generics.ListAPIView):
    def get_queryset(self):
        product_list = Product.objects.all()
        return product_list
    serializer_class = ProductSerializer

I'm about to try DRF-extensions which provide caching functionality:

https://github.com/chibisov/drf-extensions

but the build status on github is currently saying "build failing".

My app is very read-heavy on api calls. Is there a way to cache these calls?

Thank you.

Answer

Linovia picture Linovia · Jul 13, 2016

Ok, so, in order to use caching for your queryset:

class ProductListAPIView(generics.ListAPIView):
    def get_queryset(self):
        return get_myobj()
    serializer_class = ProductSerializer

You'd probably want to set a timeout on the cache set though (like 60 seconds):

cache.set(cache_key, result, 60)

If you want to cache the whole view:

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)