无法在Django中删除特定条目的缓存

14

当特定条目被保存时,我想使用信号来清除缓存。

我正在使用django-annoying的装饰器(signalsrender_to)。

@signals.post_save(sender=Artigo)
def artigo_post_save(instance, **kwargs):

    from django.http import HttpRequest
    from django.utils.cache import get_cache_key
    from django.core.cache import cache

    # cache.delete(instance.get_absolute_url()) # not work

    request = HttpRequest()
    request.method = "GET"
    request.path = '/' + instance.get_absolute_url()

    print 'request path: ', request.path

    key = get_cache_key(request=request, 
                        key_prefix=settings.CACHE_MIDDLEWARE_KEY_PREFIX)

    print "found key" if cache.has_key(key) else "notfound key"

    if cache.has_key(key):
        cache.delete(key)
        cache.set(key, None, 0)
  • 问题是,当我保存模型时,会得到输出"notfound key",因此缓存仍然没有清除
  • request.path 指向我的入口路径。

一些设置:

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
CACHE_MIDDLEWARE_KEY_PREFIX = 'cache'
CACHE_MIDDLEWARE_SECONDS = 600

CACHES = {
    'default': {
            'LOCATION': '',
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
     },
}

和视图:

@cache_page(60 * 60)
@render_to('artigo.html')
def artigo(request, categoria_slug, extra_slug="", artigo_slug=""):
    ...

感谢您。 编辑:
我进行了Ilvar的更改,现在返回“找到键”,但我仍然无法删除缓存:
    key = _generate_cache_header_key(key_prefix=settings.CACHE_MIDDLEWARE_KEY_PREFIX, request=request)
    key = key.replace(settings.LANGUAGE_CODE, settings.LANGUAGES[0][0])

Conf:

LANGUAGE_CODE = 'pt-BR'

LANGUAGES = (
        ('pt-BR','Portugues'),
)
  • 当我重新启动Gevent服务器时,才能更新内容。

你的计算出来的 key 值和 CacheMiddleware 中的值不同,需要观察 django/middleware/cache.pyFetchFromCacheMiddlewareUpdateCacheMiddleware 中的 cache_key 值。可以使用调试器或打印语句来观察。 - gerdemb
2
为了检查问题是否可重现,请尝试将缓存引擎替换为像memcached或redis这样的东西。 - alecxe
如果您正在使用语言环境,则get_cache_key还会使用语言代码来构建缓存键,请将此添加到您的代码中→ request.LANGUAGE_CODE = settings.LANGUAGE_CODE。 - Mario César
request.path = '/' + instance.get_absolute_url() 这句话应该改成 request.path = instance.get_absolute_url(),对吗? - Thomas
1
正如@alecxe所指出的那样,尝试使用除了本地内存之外的其他缓存,特别是在使用gevent驱动的服务器时,可能是一个线程问题...或者如果可能的话,再次尝试使用Django的runserver... - Bernhard Vallant
1个回答

3

cache.set(key, None, 0)应该足够了,我之前一直用这种方式清除缓存键。

如果可以的话,您可以尝试使用cache.clear()来全部清除缓存吗?只是为了看看它是否起作用。

您的缓存键都不能删除吗?这个输出结果符合预期吗?

cache.set('testkey', 'testvalue', 600)
cache.get('testkey')
cache.delete('testkey')
cache.get('testkey')
cache.set('testkey', 'testvalue2', 600)
cache.set('testkey', 'another value', 600)
cache.get('testkey')

你试过使用另一个缓存后端吗?看起来你做的一切都是正确的。

也许错误在于后端,可能是某些配置不允许它覆盖键或其他奇怪的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接