web-dev-qa-db-ja.com

キャッシュする方法Django Rest Framework API呼び出し?

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のビルドステータスは現在「ビルド失敗」と言っています。

私のアプリは、API呼び出しで非常に読み取りが多いです。これらの呼び出しをキャッシュする方法はありますか?

ありがとうございました。

23
Kakyoin

それでは、クエリセットにキャッシュを使用するには、次のようにします。

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)
37
Linovia

シリアライザーで使用するためにこれを実装しました

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)
1
Marco Silva

これを試してくださいDjango app 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)
0
naren