Проверка на пустой набор запросов в Django
Какова рекомендуемая идиома для проверки, дал ли запрос какие-либо результаты?
Пример:
orgs = Organisation.objects.filter(name__iexact = 'Fjuk inc')
# If any results
# Do this with the results without querying again.
# Else, do something else...
Я предполагаю, что есть несколько различных способов проверить это, но я хотел бы знать, как опытный пользователь Django сделает это. Большинство примеров в документации просто игнорируют случай, когда ничего не было найдено...
7 ответов
Начиная с версии 1.2, Django имеет QuerySet. Существует метод (), который является наиболее эффективным:
if orgs.exists():
# Do this...
else:
# Do that...
Но если вы все равно собираетесь оценивать QuerySet, лучше использовать:
if orgs:
...
Для получения дополнительной информации прочтите документацию QuerySet.exists().
Чтобы проверить пустоту набора запросов:
if orgs.exists():
# Do something
или вы можете проверить первый элемент в наборе запросов, если он не существует, он вернет None
:
if orgs.first():
# Do something
Если у вас огромное количество объектов, это может (иногда) быть намного быстрее:
try:
orgs[0]
# If you get here, it exists...
except IndexError:
# Doesn't exist!
Над проектом я работаю с огромной базой данных, not orgs
400+ мс и orgs.count()
250 мс В моих наиболее распространенных случаях использования (в тех случаях, когда есть результаты), эта техника часто сводится к тому, что до 20 мс. (Один случай, который я обнаружил, был 6.)
Конечно, это может быть намного дольше, в зависимости от того, как далеко база данных должна искать, чтобы найти результат. Или даже быстрее, если он быстро его находит; YMMV.
РЕДАКТИРОВАТЬ: это часто будет медленнее, чем orgs.count()
если результат не найден, особенно если условие, по которому вы фильтруете, является редким; в результате это особенно полезно в функциях представления, где вам нужно убедиться, что представление существует или выдать Http404. (Где можно было бы надеяться, люди спрашивают URL-адреса, которые существуют чаще, чем нет.)
Самый эффективный способ (до django 1.2) это:
if orgs.count() == 0:
# no results
else:
# alrigh! let's continue...
Я не согласен с предикатом
if not orgs:
Так должно быть
if not orgs.count():
У меня была та же проблема с довольно большим набором результатов (~150 тыс. Результатов). Оператор не перегружен в QuerySet, поэтому результат фактически распаковывается в виде списка перед проверкой. В моем случае время исполнения сократилось на три порядка.
Вы также можете использовать это:
if(not(orgs)):
#if orgs is empty
else:
#if orgs is not empty
Ты можешь использовать len
или же last()
if not len(orgs):
# if queryset is empty do something
if not orgs.last():
# if queryset is empty do something