【问题标题】:Caching must be implemented at view level, in models or in serializers in Django缓存必须在视图级别、模型或 Django 的序列化程序中实现
【发布时间】:2021-06-03 20:00:44
【问题描述】:

我有一个使用 Django Rest Framework 完全基于 REST API 的 Web 应用程序。我已经看到,在大多数地方,我的 API 的响应没有改变或不经常改变,所以我正在考虑缓存这些 API,为此,我正在使用 https://pypi.org/project/redis/ 包。所以我的问题是实现缓存的更好方法是什么,它应该在视图级别、模型级别或序列化程序中。怎么可能做到?

【问题讨论】:

    标签: python django caching


    【解决方案1】:

    您可以将 Cache for APIview 和 ViewSets 与 cache_page 等装饰器一起使用。

    注意:cache_page 装饰器仅缓存状态为 200 的 GET 和 HEAD 响应。

    例如:

    from django.utils.decorators import method_decorator
    from django.views.decorators.cache import cache_page
    
    class UserViewSet(viewsets.ViewSet):
        # Cache requested url for each user for 2 hours
        @method_decorator(cache_page(60*60*2))
        def list(self, request, format=None):
            content = {
                'user_feed': request.user.get_user_feed()
            }
            return Response(content)
    

    或者

    class PostView(APIView):
    
        # Cache page for the requested url
        @method_decorator(cache_page(60*60*2))
        def get(self, request, format=None):
            content = {
                'title': 'Post title',
                'body': 'Post content'
            }
            return Response(content)
    

    DRF cache docs.

    settings.py:

    # Enable memcache
    # https://devcenter.heroku.com/articles/memcache#using_memcache_from_python
    CACHES = {
        'default': {
            'BACKEND': 'django_pylibmc.memcached.PyLibMCCache'
        }
    }
    

    如果您只想存储方法或查询的结果并存储未来请求,您可以为其定义一个键并将该结果设置为使用cache.set(cache_key, result, expire_time) 的键,然后在任何时候获取它(cache.get(cache_key))你要。 请记住,您应该为结果定义一个缓存后端。正确和更好的解决方案是使用 redis 或 memcached 等消息代理来存储缓存。根据您的需要。

    //更新//

    检查数据是否已经兑现。

        class WeatherView(APIView):
            def get(self):
                if(cache.get('weatherdata') == None):
                    url = 'https://api.openweathermap.org/data/2.5/forecast?q=' + '...';
                    serialized_data = urlopen(url).read()
                    data = json.loads(serialized_data)
                    print(data)
        
                    cache.set('weatherdata', data, 3600)
                else:
                    data = cache.get('weatherdata')
        
                serializer_class = WeatherSerializer(data)
        
                responseJSON = JSONRenderer().render(serializer_class.data)
        
                return Response(responseJSON)
    

    【讨论】:

    • 我不想缓存整个APIView,我只想缓存方法响应,但是在哪里缓存,是优先考虑
    • 这里只缓存get方法,而不是缓存整个APIView。How to set cached in response headers?
    猜你喜欢
    • 2021-06-08
    • 2017-10-20
    • 1970-01-01
    • 2022-01-04
    • 2019-10-07
    • 2012-11-08
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多