Django仍然使用@never_cache装饰器缓存视图

wlp8pajw  于 2023-01-31  发布在  Go
关注(0)|答案(3)|浏览(109)

我在Django Rest Framework和uWSGI中使用Django,我在服务器上设置了memcached,并在pylibmc后端设置了memcached,我为Django配置了按站点缓存,所以除了我使用@never_cache装饰器豁免的视图之外,所有视图都应该被缓存,我不明白为什么Django添加了@never_cache装饰器后还在尝试缓存我的API视图。我有一个支持草稿模型读写操作的API。当我使用UpdateAPIView更新草稿,然后刷新页面时,它仍然显示更新前的草稿数据。我已经确认它不是浏览器端缓存,因为网络日志显示200响应,而不是304。如果清除memcached并刷新页面,那么更新后的Draft将正确返回。
最近当我把Django从1.8升级到1.10的时候,~15 pip包依赖项,OS发行版和它的包(所以很难精确地指出是什么导致了它)。
DRF检索API视图

from django.views.decorators.cache import never_cache

class DraftDetail(generics.RetrieveAPIView):
    queryset = Draft.objects.all()
    serializer_class = DraftSerializer
    permission_classes = (permissions.IsAuthenticated, HasReadWriteAccess)

    @never_cache
    def dispatch(self, *args, **kwargs):
        return super(DraftDetail, self).dispatch(*args, **kwargs)

我也尝试了基于类的替代方法@method_decorator,但没有变化:

from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator

@method_decorator(never_cache, name='dispatch')
class DraftDetail(generics.RetrieveAPIView):
    queryset = Draft.objects.all()
    serializer_class = DraftSerializer
    permission_classes = (permissions.IsAuthenticated, HasReadWriteAccess)

settings.py

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
    }
}
PYLIBMC_MIN_COMPRESS_LEN = 250
# The cache alias to use for storage.
CACHE_MIDDLEWARE_ALIAS = 'default'
# The number of seconds each page should be cached.
CACHE_MIDDLEWARE_SECONDS = 500
CACHE_MIDDLEWARE_KEY_PREFIX = 'app'

MIDDLEWARE_CLASSES = (
    'django.middleware.cache.UpdateCacheMiddleware',
    (...),
    'django.middleware.cache.FetchFromCacheMiddleware',
)

我还在请求头中设置了Cache-Control:max-age=0。

4ioopgfo

4ioopgfo1#

也许吧

@method_decorator(never_cache())
tuwxkamq

tuwxkamq2#

即使在向dispatch方法添加装饰器时,也应该使用method_decorator
Django 的官方文件说:
类上的方法与独立函数并不完全相同,因此您不能只对方法应用函数装饰器-您需要首先将其转换为方法装饰器。
never_cache装饰器没有得到任何参数;所以应该不用圆括号。也许这样就行了

@method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
    ....
e37o9pze

e37o9pze3#

我遇到了与DRF ModelViewset相同的问题,发现它是由this SO answer中所述的范围问题引起的
这是我最初定义视图集的方式,注意查询集在类定义中,这意味着它只运行一次。

class ActivityCategoryViewSet(viewsets.ModelViewSet):
queryset = ActivityCategory.objects.all()
permission_classes = [IsAuthenticatedOrReadOnly, ]

def list(self, request, *args, **kwargs):
    serializer = ActivityCategorySerializer(self.queryset, many=True)
    return Response(serializer.data)

缓存问题通过将查询集移到列表方法中解决:

class ActivityCategoryViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticatedOrReadOnly, ]

def list(self, request, *args, **kwargs):
    serializer = ActivityCategorySerializer(ActivityCategory.objects.all(), many=True)
    return Response(serializer.data)

相关问题