2016-06-12 6 views
4

モデル:ジャンゴ作る1000の重複クエリ

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) 

ノードを介して繰り返し処理することと同じ効果(> 1000年クエリ)を有しています。

+0

ツールバーで、トレースバックを表示することはできますか?私はあなたがSQLまたは何かの側面をクリックすることができると思う – TankorSmash

答えて

3

関連するオブジェクトを参照すると、繰り返しのすべてのオブジェクトがデータベースにヒットするため、重複したクエリが発生します。

ビューメソッドでselect_relatedを試してみてください。

おそらくdjangoプリフェッチを使用して関連するか選択するとそれが解決されますが、うまくいかない場合は未処理のクエリが必要です。

Djangoクエリの最適化について読んだことはありますか?ここには多くのことを説明する簡単なチュートリアルがあります:http://bookofstranger.com/optimizing-django-orm-queries-for-best-performance/

1

私はMPTTモデルで同様の問題がありました。それはselect_related (親の外部キーも)で解決されました。だから、 、あなたのニーズに応じて、適切なクエリセットがどのように見えることがあります。あなたが同様にあなたのループ内でのコメントの子を必要とする場合も

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

が、それはそのように最適化することができます。

queryset.prefetch_related('children') 

あるいはそのような:

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

...と木の深さに応じて、あなたはそれを使用することができます

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