Python 如何缓存 Django Rest Framework API 调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38320008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 20:39:09  来源:igfitidea点击:

How to cache Django Rest Framework API calls?

pythondjangocachingdjango-rest-frameworkmemcached

提问by Kitti Wateesatogkij

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

我使用 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

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

但是当与 django-rest-framework api 调用一起使用时它不起作用:

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:

我将尝试提供缓存功能的 DRF 扩展:

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

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

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

但 github 上的构建状态目前显示“构建失败”。

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

我的应用程序对 api 调用的读取量很大。有没有办法缓存这些调用?

Thank you.

谢谢你。

回答by Linovia

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):

您可能希望在缓存集上设置超时(例如 60 秒):

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)

回答by Marco Silva

I just implemented this to use on my serializers

我刚刚实现了这个以在我的序列化程序上使用

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

then i override the to_representation method on my serializers, so it caches the serialized output per instance.

然后我覆盖了序列化程序上的 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)