2009-11-11 9 views
1

Je rencontre des problèmes de performances avec Django en raison des relations m2m. J'ai une liste d'objets Something qui ont tous Something_instance.item_set, donc j'appelle Something_instance.item_set.all() plusieurs fois. Je voudrais mettre cette requête en cache dans Something_instance pour ne pas avoir à exécuter autant de requêtes. Est-ce possible? (Ceci est essentiellement un hack pour obtenir select_related() pour travailler pour m2m).Ajout de mini-caches aux modèles django

EDIT: Les 2 extraits suivants montrent le problème que je rencontre. Dans views.py, j'interroge la relation m2m.

for t in items: 
      try: 
       t.price = t.user_item_rel_set.get(user=u).payment_amount 
      except: 
       t.price = -1 * t.buyer_item_rel_set.get(buyer=u).payment_amount 
    return items 

En outre, une fonction dans mon modèle:

def listBuyers(self): 
    return self.buyer_item_rel_set.all() 

J'ai parce que je l'utilise dans mon modèle pour obtenir des informations à partir de ces éléments.

L'interrogation des relations m2m s'exécute deux fois: une fois dans le fichier views.py, puis une fois dans le modèle. Je voudrais obtenir le jeu de queues dans les vues, l'attacher à l'instance du modèle, puis l'alimenter au modèle, de sorte qu'il (et le code views.py) utilise le jeu de queues mis en cache, au lieu de récupérer à nouveau.

Répondre

4

Oui, je le fais tout le temps. En utilisant votre méthode listBuyers comme un exemple (par la voie, convention Pythonic serait de l'appeler list_buyers ...)

def listBuyers(self): 
    if not hasattr(self, '_buyers'): 
     self._buyers = self.buyer_item_rel_set.all() 
    return self._buyers 

Cela frappera la base de données la première listBuyers de temps est appelé à un cas particulier, mais pas après .

+0

Mais dans ce cas, 'self' fait référence à un modèle Django, donc je ne peux pas ajouter de choses dessus. – victor

+0

Pourquoi pas? Bien sûr vous pouvez. Vous pouvez ajouter ce que vous voulez à n'importe quel objet Python. (Self fait référence à l'instance, pas le modèle, bien sûr.) –

+0

Un simple test: x = Item.objects.all() [0] = ' x._test aoeu' print x._test la ci-dessus échouera. – victor

0

La requête est déjà mise en cache. Voir le Django FAQ pour plus d'informations sur how to view SQL queries qui sont générés lors du chargement d'une page.

Le problème peut être aussi simple qu'un index manquant (bien que l'ORM de Django devrait générer les index nécessaires) ou un code inefficace utilisant les résultats du QuerySet. Nous aurions besoin de beaucoup plus d'informations pour aider à résoudre les problèmes.

+0

Edité ci-dessus pour afficher le code qui est beaucoup interrogation. En raison des appels ultérieurs à cette relation m2m, il frappe à nouveau la DB plusieurs fois. – victor

0

Difficile à dire sans voir vos modèles et leurs relations (fe comment « t » liés à l'utilisateur « u »)

Mais la suggestion est frappé tous liés à des éléments utilisateur (« u ») à une requête et que d'aller un par un et calculer des choses nécessaires ...

BTW .. « t » et « u » ne sont pas très bons noms pour les variables