Выбор ответа Junior Django ORM и N+1 обновлено

exists() и count() вместо загрузки строк

Вопрос

Нужно только узнать, есть ли у пользователя неоплаченные заказы. Что эффективнее?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Order.objects.filter(user=u, paid=False).exists(). exists() выполняет SELECT 1 ...

Варианты ответа

  1. if Order.objects.filter(user=u, paid=False):
  2. Order.objects.filter(user=u, paid=False).exists()правильный ответ
  3. len(Order.objects.filter(user=u, paid=False)) > 0
  4. list(Order.objects.filter(user=u, paid=False))

Разбор

exists() выполняет SELECT 1 ... LIMIT 1 и ничего не загружает. Проверка истинности QuerySet и len() выполняют полный запрос и создают все объекты моделей. Это оправдано только если строки потом всё равно понадобятся (тогда кеш QuerySet переиспользуется).

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.