2009-10-26 3 views
3

J'ai implémenté la mise en cache dans mon application django et utilisé la mise en cache par vue via l'API de cache et la mise en cache des fragments de gabarit. Sur certaines de mes pages, j'utilise un tag de modèle django personnalisé, ce tag est fourni via un développeur tiers, il prend des arguments dans ses balises de template, puis envoie une requête à un serveur distant, renvoie la réponse par XML, puis rend le résultat dans ma page. Grand - Je pensais que je pouvais facilement mettre en cache les en utilisant la mise en cache de fragments, donc je:La mise en cache des fragments de gabarit ne semble pas fonctionner pour certaines balises de gabarit personnalisées

{% load cache %} 
{% cache 500 request.user.username %} 
{% load third party custom tags %} 
{% expensive custom tag set that gets stuff from a third party server via xml %} 
{{ some.stuff}} 
{% endcache %} 

Le problème est peu importe ce que je fais, les demandes se encore décocha à ce serveur à distance, il semble Django n'aime pas mettre en cache ces balises de modèle personnalisé. Je sais que memcached fonctionne très bien, pour d'autres vues et modèles, tout fonctionne très bien. Est-ce que je fais quelque chose qui est incompatible avec la mise en cache des fragments? Y a-t-il un moyen de contourner cela?

Répondre

0

Avez-vous essayé d'utiliser un nom différent pour le fragment de cache? Il pourrait y avoir un problème avec l'utilisation request.user.username pour deux raisons:

  • Si un utilisateur n'est pas connecté, request.user.username pourrait être vide, résultant en un non nommé cache fragment

  • Si un utilisateur est connecté, cela appeler la 3e balise de modèle de fête à moins une fois pour chaque utilisateur tous les 3 mintues

Peut-être qu'il vaut la peine d'essayer de renommer le nom du fragment de cache pour le test:

{% cache 500 customxml %} 

Je voudrais aussi essayer de charger de la 3e balise de modèle de partie en dehors de la balise de cache comme ceci:

{% load cache third_party_custom_tags %} 
{% cache 500 request.user.username %} 
{% expensive custom tag set that gets stuff from a third party server via xml %} 
{{ some.stuff}} 
{% endcache %} 

Ce que je Je ne suis pas sûr de si le cadre de cache met en cache les résultats d'un tag de modèle. Si cela ne fonctionne pas, jetez un coup d'œil à ce que fait la balise template sous le capot et réimplémentez la balise template en utilisant le low-level cache de Django.

+0

Mais ne changerait-il pas le nom en "customxml" serait un désastre? Est-ce que cela ne montrerait pas les données des utilisateurs les uns aux autres - ou, plutôt, montrerait à tous les utilisateurs les données de tous les autres qui visitent ensuite la page? –

+0

Cela dépend de l'objectif de la balise template. Est-ce que les données sont sensibles et uniques à l'utilisateur? Si oui, je serais d'accord et il serait préférable d'utiliser le cache de bas niveau et ré-implémenter la balise de modèle. Si les données sont les mêmes pour chaque utilisateur, l'utilisation de "customxml" serait acceptable. – richleland

0

Je pense que le problème est la balise personnalisée, comme vous l'avez suggéré. Je ne suis pas d'accord avec le fait que le request.user.username est un problème, car la documentation pour le sujet le donne comme exemple, et je l'ai utilisé avec la mise en cache interne (nombre de messages, par exemple), en test, et ça a bien fonctionné. Le cache de bas niveau est potentiellement utile, mais je regarderais votre tag personnalisé pour voir ce qui ne serait pas en cache. Sans le code, c'est difficile à deviner, mais je suppose que quelque chose comme l'heure, ou une autre variable, est renvoyée qui l'oblige à forcer une mise à jour (si le XML extrait des données qui changent Django peut forcer une mise à jour, selon sur d'autres paramètres). J'ai eu des résultats mitigés avec la mise en cache de Django, donc j'examinerais vos flux XML pour voir si cela cause quelque chose d'arrêter la mise en cache.

0

Je ne pense pas que cela ait quelque chose à voir avec l'étiquette personnalisée.

Nous avons réécrit la balise de mise en cache Django car nous avions besoin de plus de contrôle que ce qui était possible avec celui fourni.Vous pouvez en faire une copie vous-même et y coller quelques instructions d'impression de débogage. En particulier, vérifiez le nom de fichier (en supposant que vous mettez en cache les fichiers) et voyez ce qui est généré. Il se pourrait que cela change quand ce n'est pas le cas (pour une raison inconnue) et cela voudrait dire qu'il faut toujours faire un nouveau rendu puis bloquer le bloc.

Regardez dans django/templatetags/cache.py. Ce n'est que 63 lignes de code.

3

Si le fragment de modèle que vous essayez de mettre en cache ne peut pas être décapé, memcached ne pourra pas le stocker et déclenchera une exception. De ce que je peux rassembler, les exceptions générées lors du rendu des modèles Django sont supprimées. Étant donné que votre balise personnalisée effectue des requêtes HTTP, des objets socket (qui ne peuvent pas être décapés) sont peut-être stockés dans le fragment de modèle.

Si tel est le cas, la seule façon de contourner cela serait de modifier la balise personnalisée pour se débarrasser des objets socket restants.

Questions connexes