2016-06-12 3 views
4

Modèle:Django Faire 1000 requêtes en double

class Comment(MPTTModel): 

    submitter = models.ForeignKey(User, blank=True, null=True) 
    post = models.ForeignKey(Post, related_name="post_comments") 
    parent = TreeForeignKey('self', blank=True, null=True, related_name="children") 
    text = models.CharField("Text", max_length=1000) 
    rank = models.FloatField(default=0.0) 
    pub_date = models.DateTimeField(auto_now_add=True) 

à travers des noeuds a Itération le même effet (> 1000 requêtes).

+0

Avec la barre d'outils, pouvez-vous montrer le retraçage inclus? Je pense que vous pouvez cliquer sur le côté de la sql ou quelque chose – TankorSmash

Répondre

3

requêtes dupliquées se produit parce que tous les objets de la base itération frappe de données lorsque vous parrainez un objet associé.

Essayez d'utiliser select_related dans votre méthode de vue.

probablement en utilisant prélecture django liés ou connexes sélectionnez résoudra, mais si le travail non, excusez-moi, vous aurez besoin d'une requête brute.

Avez-vous déjà lu sur l'optimisation des requêtes Django? Voici un tutoriel simple qui est d'expliquer beaucoup de choses: http://bookofstranger.com/optimizing-django-orm-queries-for-best-performance/

1

J'ai eu problème similaire avec des modèles de MPTT. Il a été résolu avec select_related (également pour les clés étrangères du parent). Ainsi, selon vos besoins, queryset appropriée peut ressemble:

Comment.objects.select_related('post', 'submitter', 'parent', 'parent__submitter', 'parent__post') 

En outre, si vous avez besoin des enfants de commentaire dans votre boucle ainsi, il peut être optimisé comme ça:

queryset.prefetch_related('children') 

Ou même comme ça:

queryset.prefetch_related(
    Prefetch(
     'childred', 
     queryset=Comment.objects.select_related('post'), 
     to_attr='children_with_posts' 
    ) 
) 

... et en fonction de la profondeur de l'arbre, vous pouvez l'utiliser:

queryset.select_releated('parent', 'parent__parent', 'parent__parent__parent') 
# you got the idea:)