2012-03-05 6 views
2

je balise cache dans le modèle de base:Invalider cache particulier

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

Quand j'ajouter une nouvelle catégorie par admin de Django, je veux annuler ce cache:

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

     cache.delete('categories') 

Mais le cache est de rester valide ! Qu'est-ce qui ne va pas?

Répondre

3

C'est parce que la clé réelle est pas « catégories », mais plutôt celui qui est construit dynamiquement par Django en utilisant les éléments suivants:

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

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

En général, la clé va être dans le format: template.cache.categories.[hexdigest]. Donc, la partie difficile est de déterminer la partie hexdigest.

Je trouve le Django snippet (dans les commentaires) suivant, qui ressemble elle devrait encore fonctionner (à partir de 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) 

Puisque vous n'êtes pas passer des variables à varier à la templatetag, vous peut appeler cela avec juste: invalidate_template_cache('categories'). Sinon, vous devrez passer une liste de toutes les variables sur lesquelles la balise de template varie en tant que deuxième argument.

+0

Merci, ça fonctionne très bien! Pourquoi ça n'est toujours pas dans les fonctions natives de Django! – Deadly

+2

Dans Django 1.4.X le md5_constructor n'est pas utilisé et vous devez utiliser hashlib à la place. args = hashlib.md5 (u ':'. join ([urlquote (variable_de_résolution (var, context)) pour var dans self.vary_on])) – margusholland

0

Dans Django 1.6+ s'il vous plaît utiliser make_template_fragment_key:

django.core.cache.utils.make_template_fragment_key(fragment_name, vary_on=None) Si vous souhaitez obtenir la clé de cache utilisé pour un fragment en cache, vous pouvez utiliser make_template_fragment_key. fragment_name est le même que le second argument de la balise template du cache; vary_on est une liste de tous les arguments supplémentaires passés à la balise. Cette fonction peut être utile pour ou invalidant un élément mis en cache d'écraser, par exemple:

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 

fonctionne comme par magie :-)

Questions connexes