2012-03-05 1 views
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') 

Но кэш остаются в силе ! Что не так?

ответ

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]. Таким образом, сложная часть вычисляет шестнадцатиричную часть.

Я нашел следующее 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) 

Поскольку вы не передаете переменные варьировать от к templatetag, вы может назвать это с помощью только: invalidate_template_cache('categories'). В противном случае вам нужно будет передать список всех переменных, в которых тег шаблона изменяется в качестве второго аргумента.

+0

Спасибо, что работает отлично! Почему он все еще не работает в собственных функциях Django! – Deadly

+2

В Django 1.4.X md5_constructor не используется, и вместо этого вы должны использовать hashlib. args = hashlib.md5 (u ':'. join ([urlquote (resolve_variable (var, context)) для var in self.vary_on])) – margusholland

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. имя_файла совпадает с вторым аргументом тега шаблона кэша; variable_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 

работает как Magic :-)