Mam tag pamięci podręcznej w szablonie podstawowym:

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

Kiedy dodaję nową kategorię przez administratora Django, chcę unieważnić tę pamięć podręczną:

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

        cache.delete('categories')

Ale pamięć podręczna pozostaje ważna! Co jest nie tak?

2
Deadly 5 marzec 2012, 18:08

2 odpowiedzi

Najlepsza odpowiedź

Dzieje się tak dlatego, że rzeczywisty klucz to nie „kategorie”, ale raczej taki, który jest dynamicznie konstruowany przez Django przy użyciu następującego:

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())

Zobacz: https://code.djangoproject .com/browser/django/tags/releases/1.3.1/django/templatetags/cache.py

Ogólnie klucz będzie miał format: template.cache.categories.[hexdigest]. Więc trudną częścią jest wymyślenie części szesnastkowej.

Znalazłem następujący fragment Django (w komentarzach), który wygląda na to, że nadal powinien działać (od 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)

Ponieważ nie przekazujesz żadnych zmiennych do udostępnienia tagowi szablonu, możesz to wywołać za pomocą: invalidate_template_cache('categories'). W przeciwnym razie jako drugi argument musisz przekazać listę wszystkich zmiennych, których tag szablonu zmienia.

3
Chris Pratt 5 marzec 2012, 19:40

W Django 1.6+ użyj make_template_fragment_key:

django.core.cache.utils.make_template_fragment_key(fragment_name, vary_on=None) Jeśli chcesz uzyskać klucz pamięci podręcznej używany dla fragmentu pamięci podręcznej, możesz użyć make_template_fragment_key. fragment_name jest taki sam jak drugi argument znacznika szablonu pamięci podręcznej; Vari_on to lista wszystkich dodatkowych argumentów przekazanych do tagu. Ta funkcja może być przydatna do unieważniania lub nadpisywania elementu w pamięci podręcznej, na przykład:

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

Działa jak magia :-)

0
Alexei Martchenko 8 czerwiec 2015, 22:00