使特定缓存无效

时间:2012-03-05 14:08:16

标签: django django-cache

我在基本模板中有缓存标记:

{% cache 100000 categories %}
    Categories output
{% endcache %}

当我通过Django管理员添加新类别时,我想要使此缓存无效:

class CategoriesAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        super(CategoriesAdmin, self).save_model(request, obj, form, change)

        cache.delete('categories')

但缓存仍然有效!有什么问题?

2 个答案:

答案 0 :(得分:3)

那是因为实际的键是不是“categories”,而是由Django使用以下内容动态构建的键:

args = md5_constructor(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())

请参阅:https://code.djangoproject.com/browser/django/tags/releases/1.3.1/django/templatetags/cache.py

通常,密钥的格式为:template.cache.categories.[hexdigest]。因此,棘手的部分是找出hexdigest部分。

我发现以下Django snippet(在评论中)看起来应该仍然有用(从2009年开始):

from django.core.cache import cache
from django.utils.hashcompat import md5_constructor
from django.utils.http import urlquote

def invalidate_template_cache(fragment_name, *variables):
    args = md5_constructor(u':'.join([urlquote(var) for var in variables]))
    cache_key = 'template.cache.%s.%s' % (fragment_name, args.hexdigest())
    cache.delete(cache_key)

由于您没有传递任何变量以改变模板标签,因此您可以使用invalidate_template_cache('categories')来调用它。否则,您需要传递模板标记变化的所有变量的列表作为第二个参数。

答案 1 :(得分:0)

在Django 1.6+中,请使用make_template_fragment_key

django.core.cache.utils.make_template_fragment_key(fragment_name, vary_on=None)如果要获取用于缓存片段的缓存密钥,可以使用make_template_fragment_key。 fragment_name与缓存模板标记的第二个参数相同; vary_on是传递给标记的所有其他参数的列表。此函数可用于使缓存项无效或覆盖,例如:

from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key
# cache key for {% cache 500 sidebar username %}
key = make_template_fragment_key('sidebar', [username])
cache.delete(key) # invalidates cached template fragment

像魔术一样工作: - )