我在基本模板中有缓存标记:
{% 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')
但缓存仍然有效!有什么问题?
答案 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
像魔术一样工作: - )