2

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

{% 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')

但缓存保持有效!怎么了?

4

2 回答 2

3

这是因为实际的键不是“类别”,而是由 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 片段(在评论中),看起来它应该仍然有效(从 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')。否则,您需要传入模板标记所依赖的所有变量的列表作为第二个参数。

于 2012-03-05T15:40:17.207 回答
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

像魔术一样工作:-)

于 2015-06-08T19:00:41.867 回答