2016-06-12 6 views
4

Modell:Django machen 1000 doppelte Abfragen

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) 

Iterieren durch die Knoten hat den gleichen Effekt (> 1000 Abfragen).

+0

Mit der Symbolleiste, können Sie die Traceback enthalten angezeigt? Ich denke du kannst auf die Seite des Sql oder so klicken – TankorSmash

Antwort

3

Doppelte Abfragen treten auf, weil alle Objekte aus der Iteration auf die Datenbank zugreifen, wenn Sie auf ein zugehöriges Objekt verweisen.

Verwenden Sie select_related in Ihrer Ansichtsmethode.

Wahrscheinlich mit Django Prefetch verwandt oder wählen Sie im Zusammenhang damit, wird das Problem lösen, aber wenn nicht arbeiten, tut mir leid, dass Sie eine rohe Abfrage benötigen.

Haben Sie schon einmal von der Optimierung von Django-Abfragen gelesen? Hier ist ein einfaches Tutorial, das eine Menge Dinge erklärt: http://bookofstranger.com/optimizing-django-orm-queries-for-best-performance/

1

Ich hatte ähnliches Problem mit MPTT-Modellen. Es wurde mit select_related (auch für fremde Fremdschlüssel) gelöst. Also, je nach Bedarf, richtiger queryset kann wie folgt aussieht:

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

Auch, wenn Sie auch Kommentar der Kinder in der Schleife, dann kann es so optimiert werden:

queryset.prefetch_related('children') 

Oder sogar wie folgt aus:

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

... und je nach Baumtiefe, können Sie verwenden:

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