Recherche de queryset vide dans Django

Quel est l'idiome recommandé pour vérifier si une requête a renvoyé des résultats?
Exemple:

orgs = Organisation.objects.filter(name__iexact = 'Fjuk inc')
# If any results
    # Do this with the results without querying again.
# Else, do something else...

Je suppose qu'il existe plusieurs façons de vérifier cela, mais j'aimerais savoir comment un utilisateur Django expérimenté le ferait. La plupart des exemples dans les documents ignorent simplement le cas où rien n'a été trouvé...

122
demandé sur Niklas 2009-09-07 09:50:42

7 réponses

if not orgs:
    # Do this...
else:
    # Do that...
123
répondu Adam 2009-09-07 05:53:34

Depuis la version 1.2, Django a QuerySet.existe() la méthode qui est le plus efficace:

if orgs.exists():
    # Do this...
else:
    # Do that...

Mais si vous allez évaluer QuerySet de toute façon, il est préférable d'utiliser:

if orgs:
   ...

Pour plus d'informations lire QuerySet.exists () documentation .

147
répondu Leonid Shvechikov 2016-10-02 14:38:09

Si vous avez un grand nombre d'objets, cela peut (parfois) être beaucoup plus rapide:

try:
    orgs[0]
    # If you get here, it exists...
except IndexError:
    # Doesn't exist!

Sur un projet sur lequel je travaille avec une énorme base de données, not orgs est 400 + ms et orgs.count() est 250ms. dans Mes cas d'utilisation les plus courants (ceux où il y a des résultats), cette technique descend souvent à moins de 20ms. (un cas que j'ai trouvé, c'était 6.)

Pourrait être beaucoup plus long, bien sûr, en fonction de la distance que la base de données doit chercher pour trouver un résultat. Ou encore plus vite, s'il en trouve un rapidement; YMMV.

EDIT: Ce sera souvent être plus lent que orgs.count() si le résultat n'est pas trouvé, en particulier si la condition que vous êtes le filtrage est une rare; en conséquence, il est particulièrement utile dans les fonctions d'affichage où vous devez assurez-vous que le point de vue existe, ni de jeter Http404. (Où, on l'espère, les gens demandent des URL qui existent le plus souvent.)

15
répondu Adam Playford 2010-01-20 00:23:16

Pour vérifier le vide d'un queryset:

if orgs.exists():
    # Do something

Ou vous pouvez vérifier le premier élément d'un queryset, s'il n'existe pas, il retournera None:

if orgs.first():
    # Do something
10
répondu Tuss4 2015-04-20 13:56:51

Je ne suis pas d'accord avec le prédicat

if not orgs:

, Il devrait être

if not orgs.count():

J'avais le même problème avec un jeu de résultats assez important (~150k résultats). L'opérateur n'est pas surchargé dans QuerySet, de sorte que le résultat est réellement décompressé en tant que liste avant la vérification. Dans mon cas, le temps d'exécution a diminué de trois ordres.

5
répondu hedleyroos 2011-07-30 14:33:05

Le moyen le plus efficace (avant django 1.2) est le suivant:

if orgs.count() == 0:
    # no results
else:
    # alrigh! let's continue...
5
répondu Bartosz 2012-09-13 10:09:47

Vous pouvez utiliser len ou last()

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

if not orgs.last():
     # if queryset is empty do something
0
répondu Vikram S 2018-07-10 12:29:57