Проверка пустого набора запросов в 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 сделает это. Большинство примеров в документах просто игнорируют случай, когда ничего не было найдено...

150   7  

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.существует() документация.

если у вас есть огромное количество объектов, это может (иногда) быть гораздо быстрее:

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-адреса, которые существуют чаще, чем нет.)

чтобы проверить пустоту queryset:

if orgs.exists():
    # Do something

или вы можете проверить первый элемент в queryset, если он не существует, он вернет None:

if orgs.first():
    # Do something

Я не согласен с предикатом

if not orgs:

Он должен быть!--3-->

if not orgs.count():

у меня была такая же проблема с довольно большим набором результатов (~150k результатов). Оператор не перегружается в QuerySet,поэтому результат фактически распаковывается в виде списка перед проверкой. В моем случае время исполнения сократилось на три ордера.

самый эффективный способ (до django 1.2) это:

if orgs.count() == 0:
    # no results
else:
    # alrigh! let's continue...

можно использовать len или last()

if not len(orgs):
     # if queryset is empty do something

if not orgs.last():
     # if queryset is empty do something
    Ничего не найдено.

Добавить ответ:
Отменить.