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

Django 3.0.2中get_cache_key生成不一致缓存键,视图缓存失效操作失败的问题求助

解决Django视图缓存失效时cache_header键不匹配的问题

问题分析

从你描述的情况来看,生成的cache_header键和Redis中现存的不匹配,核心原因是伪造的请求对象和实际请求的元数据不一致,同时存在reverse调用时参数传递错误的问题。Django生成缓存键时,会严格依赖请求的路径、主机信息、语言等细节,哪怕一点点差异都会导致哈希值完全不同。

具体修正步骤

1. 修正伪造请求的META字段

你当前设置的SERVER_NAME是反向解析的地址1.0.0.127.in-addr.arpa,这和实际请求的主机信息不符。需要改成和实际请求一致的主机名/IP,同时补充HTTP_HOST字段(Django的get_host()方法优先读取这个值,会直接影响缓存键生成)。

比如实际请求是127.0.0.1:8000,META应该这样设置:

request.META = {
    'SERVER_NAME': '127.0.0.1',
    'SERVER_PORT': '8000',  # 注意这里是字符串类型,和实际请求保持一致
    'HTTP_HOST': '127.0.0.1:8000',
}

2. 修正函数的参数传递逻辑

你的视图get_segment_list接收的是关键字参数(appid和page),但当前函数里用reverse(view_name, kwargs=args),而参数args默认是列表,这会导致生成的请求路径错误,进而哈希值不匹配。

修改函数定义,把args改为kwargs,并调整reverse的调用方式,同时补充删除cache_header键的逻辑:

def expire_view_cache(view_name, kwargs={}, namespace=None, key_prefix=None):
    """
    This function allows you to invalidate any view-level cache.
    view_name: view function you wish to invalidate or it's named url pattern
    kwargs: keyword arguments passed to the view function
    namespace: optional, if an application namespace is needed
    key prefix: for the @cache_page decorator for the function (if any)
    """
    from django.urls import reverse
    from django.http import HttpRequest
    from django.utils.cache import get_cache_key
    from django.core.cache import cache
    
    # 创建伪造请求对象
    request = HttpRequest()
    request.method = 'GET'  # 显式设置请求方法,避免默认值问题
    request.LANGUAGE_CODE = 'en-us'
    
    # 处理命名空间
    if namespace:
        view_name = f"{namespace}:{view_name}"
    
    # 设置正确的主机元数据
    request.META = {
        'SERVER_NAME': '127.0.0.1',
        'SERVER_PORT': '8000',
        'HTTP_HOST': '127.0.0.1:8000',
    }
    
    # 生成正确的请求路径(使用关键字参数)
    request.path = reverse(view_name, kwargs=kwargs)
    
    # 获取缓存键并删除对应的cache_page和cache_header
    key = get_cache_key(request, method='GET', key_prefix=key_prefix)
    if key:
        # 删除页面缓存
        cache.delete(key)
        # 构造并删除对应的header缓存键
        header_key = key.replace('cache_page', 'cache_header').split('.GET')[0] + f".{request.LANGUAGE_CODE}.UTC"
        cache.delete(header_key)
        return True
    return False

3. 正确调用失效函数

调用时传入视图对应的关键字参数,比如:

expire_view_cache('get_segment_list', kwargs={'appid': 'your_app_id', 'page': '1'})

额外注意点

  • 如果你的视图有查询参数(比如?foo=bar),需要在伪造请求中补充QUERY_STRING字段:request.META['QUERY_STRING'] = 'foo=bar'。
  • 确保request.LANGUAGE_CODE和实际请求的语言一致(你的Redis键里是en-us,当前设置没问题)。
  • 如果使用了自定义的key_prefix,调用时要传入对应的key_prefix参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:32:36