2009-10-19 9 views
11

J'ai récemment implémenté l'excellent framework de cache de Django. Cependant, d'après ce que je comprends, Django ne mettra pas en cache une vue qui est passée des paramètres dans une requête get. J'ai une vue Ajax qui est passée obtenir des paramètres que je voudrais mettre en cache pendant X secondes, ce qui serait un moyen facile de le faire?Cache une vue django avec des paramètres d'URL

Dans le code psuedo J'ai actuellement une URL:

http://mysites/ajaxthing/?user=foo&items=10 

Je voudrais mettre en cache toute cette URL aussi longtemps qu'il a les mêmes paramètres obtenir.

J'utilise actuellement les décorateurs de cache à mon avis:

myview(stuff) 

myview = cache_page(myview, 60 * 3) 

Je l'ai lu au sujet django's vary headers mais il est allé un peu plus de ma tête, et je ne suis même pas sûr que ce la bonne solution

+2

Y at-il une raison quelconque vous ne voulez pas il suffit d'utiliser: 'http: // mysites/ajaxthing/utilisateur/foo/items/10 /' De cette façon, vous pouvez facilement contourner ce problème. –

+0

Veuillez lire la réponse d'euqidron ci-dessous, ce comportement a changé dans Django 1.3. –

Répondre

16

droit, varient en-têtes ne sont pas la bonne solution, il est utilisé lorsque vous souhaitez mettre en cache les en-têtes de demande de client comme agent utilisateur, etc.

vous devez utiliser low-level API ou template fragment caching. Cela dépend vraiment de vos opinions.

Avec API de bas niveau, il ressemble à ceci:

from django.core.cache import cache 

def get_user(request): 
    user_id = request.GET.get("user_id") 
    user = cache.get("user_id_%s"%user_id) 
    if user is None: 
     user = User.objects.get(pk=user_id) 
     cache.set("user_id_%s"%user_id, user, 10*60) # 10 minutes 
    ... 
    .. 
    . 
+0

+1 pour la mise en cache des fragments de modèle. C'est vraiment utile dans certaines situations. –

+0

Merci pour le contour concis, c'est vraiment utile. –

8

Oui, vous pouvez utiliser django-view-cache-utils, voici le code pour votre cas:

from view_cache_utils import cache_page_with_prefix 
from django.utils.hashcompat import md5_constructor 
... 
@cache_page_with_prefix(60*15, lambda request: md5_constructor(request.get_full_path()).hexdigest()) 
def my_view(request): 
    ... 
+2

cette approche est sympa, mais nous rencontrons deux problèmes majeurs avec le code, 1. il peut y avoir conflit pour deux vues avec les mêmes arguments URL, 2. la chaîne str (request.GET) peut retourner différemment, parce que l'affichage du dictionnaire n'a pas spécifié commande. J'ai utilisé plus tard ce code à la place: @cache_page_with_prefix (60 * 15, requête lambda: md5_constructor (request.build_absolute_uri()). Hexdigest()). –

+0

Merci pour votre conseil, mise à jour de la réponse. –

1

Il semble que vous ne avez plus besoin de faire quoi que ce soit plus compliqué que de placer @cache_page ([durée]) au-dessus de votre vue fonction que vous essayez de cache, indépendamment du fait que vous avez des paramètres dans l'URL .

Par exemple, si vous avez une URL comme:

http://example.com/user/some_user_id 

Votre fonction de vue en views.py ressemblerait à quelque chose comme ceci:

from django.views.decorators.cache import cache_page 
... 

@cache_page(60 * 10) 
def get_user_detail(request, user_id=None): 
    ... 
    return render(...) 
+0

J'ai essayé ceci mais j'ai obtenu un AttributeError de l'urls.py en utilisant des vues génériques: url (r '^ (? P [0-9] +)/teams/(? P [0-9] +)/détail/$ ', vues.TeamDetailView.as_view(), name = 'team_detail'), AttributeError: l'objet 'function' n'a pas d'attribut 'as_view' – simi

Questions connexes