You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework缓存分页视图返回两种不同响应的问题

Django REST Framework分页视图缓存重复请求返回不同响应问题

问题描述

使用带有2小时缓存的DRF分页列表视图时,重复请求同一端点有时返回不同大小的响应。已排除缓存过期、数据变更、region参数不一致的可能,怀疑存在多个缓存响应但不清楚具体机制。

视图代码

class MyListView(generics.ListAPIView):
    model = MyListModel
    serializer_class = MyListSerializer
    pagination_class = PageNumberPagination
    pagination_class.page_size = 1000

    def get_queryset(self):
        region = self.kwargs.get('region')
        sort_param = '-date_created'
        return MyListModel.objects.filter(region=region).order_by(sort_param)

    @method_decorator(cache_page(2*60*60))
    def get(self, *args, **kwargs):
        return super().get(*args, **kwargs)

缓存清理代码(每日cronjob执行)

from django.core.cache import cache

cache.clear()

问题原因及解决方案

1. 缓存键受请求头干扰

cache_page默认会根据完整请求信息生成缓存键,包括Accept-Encoding(如gzip压缩标识)、User-Agent等请求头。不同客户端发送的请求头差异会导致生成不同缓存键,进而存储多个响应。

解决方法:自定义缓存键生成函数,只保留关键参数

def custom_cache_key(request, *args, **kwargs):
    # 仅保留请求路径、region参数和分页参数作为缓存键依据
    key_parts = [
        request.path,
        request.GET.get('page', '1'),
        request.resolver_match.kwargs.get('region', '')
    ]
    return ':'.join(key_parts)

class MyListView(generics.ListAPIView):
    # 其他代码不变
    @method_decorator(cache_page(2*60*60, key_func=custom_cache_key))
    def get(self, *args, **kwargs):
        return super().get(*args, **kwargs)

2. 分页参数的隐性差异

即使未显式传递page参数,部分客户端或中间件可能会自动添加隐性分页参数,导致缓存键不一致。自定义缓存键时需强制统一分页默认值(如默认page=1)。

3. 分布式缓存的一致性问题

如果使用Redis集群等分布式缓存,需确认缓存键的哈希路由规则,避免同一请求被路由到不同节点存储不同响应。同时检查缓存是否开启分片、多副本等可能导致数据不一致的配置。

4. 验证缓存键的实际生成值

临时在视图中打印缓存键,确认同一请求是否生成相同键:

from django.utils.cache import get_cache_key

class MyListView(generics.ListAPIView):
    # 其他代码不变
    def get(self, *args, **kwargs):
        key = get_cache_key(self.request)
        print(f"当前缓存键: {key}")
        return super().get(*args, **kwargs)

内容的提问来源于stack exchange,提问作者stackunderflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 09:34:51