2016-06-12 7 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 (также для внешних ключей родителя). Таким образом, в зависимости от ваших потребностей, надлежащий QuerySet может выглядеть так:

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:)