Проверка на пустой набор запросов в 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 ответов

Решение
if not orgs:
    # Do this...
else:
    # Do that...

Начиная с версии 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
Другие вопросы по тегам