Le filtrage de vide ou NULL noms dans un queryset
J'ai first_name
, last_name
& alias
(facultatif) dont j'ai besoin pour la recherche. Donc, j'ai besoin d'une requête de me donner tous les noms qui ont un alias défini.
Que si je pouvais faire:
Name.objects.filter(alias!="")
Donc, quel est l'équivalent de ce qui précède?
Vous devez vous connecter pour publier un commentaire.
Vous pourriez faire ceci:
Si vous avez besoin d'exclure les valeurs null et les cordes à vide, la meilleure façon de le faire est de relier ensemble les conditions de la sorte:
Le chaînage de ces méthodes fondamentalement vérifie chaque état indépendant: dans l'exemple ci-dessus, nous excluons les lignes où
alias
est soit null ou une chaîne vide, de sorte que vous obtenez tous lesName
les objets qui ont un non-nulle, non-videalias
champ. Le SQL généré ressemblerait à quelque chose comme:Vous pouvez également passer plusieurs arguments à un seul appel à
exclude
, qui permettrait de s'assurer que seuls les objets qui répondent à chaque condition de se faire exclure:Ici, les lignes de qui
some_field
etother_field
sont remplies de se faire exclure, nous avons donc toutes les lignes où les deux champs ne sont pas vraies. Le code SQL généré serait un peu comme ceci:Alternativement, si votre logique est plus complexe que cela, vous pouvez utiliser Django Q objets:
Pour plus d'info voir cette page et cette page dans le Django docs.
en aparté: Mon SQL exemples sont juste une analogie--la véritable code SQL généré sera probablement différent. Vous obtiendrez une meilleure compréhension de la façon Django requêtes en fait en regardant les SQL qu'ils génèrent.
OR
(uniquement dans ce cas), il produit un SQLAND
. Voir cette page: docs.djangoproject.com/en/dev/topics/db/queries/... L'avantage de chaînage est que vous pouvez mélangerexclude
etfilter
de modèle compliqué les conditions de la requête. Si vous souhaitez un modèle réel SQLOR
vous devez utiliser un Django Q objet: docs.djangoproject.com/en/dev/topics/db/queries/... Merci d'éditer votre modifier pour refléter cela, que la réponse est gravement trompeuse, car elle se trouve.OR
à fusionner les conditions. Je vais modifier ma réponse à préciser.NOT (A AND B)
est équivalent àNOT A OR NOT B
. Je pense que rend les choses encore plus confuses à nouveau Django développeurs qui savent SQL, mais ne sont pas familiers avec l'Orm.AND
dans la première requête dans unOR
parce que vous êtes à l'aide deexclude
. Dans le cas général, il est probablement plus exact de parler de chaînage comme unTHEN
, c'est à direexclude(A) THEN exclude(B)
. Désolé à propos de la dure de la langue ci-dessus. Votre réponse est vraiment bon, mais je suis inquiet au sujet de nouveaux développeurs en tenant votre réponse trop générale.AND
etOR
pourrait être utile pour quelqu'un qui vient à Django à partir d'un SQL arrière-plan. Pour une compréhension plus profonde de Django, je pense que les docs faire un meilleur travail que je peux.alias__isnull=False
condition est redondant. Si le champ estNull
sûrement, il sera exclu par le premier alinéa de l'?Tout d'abord, le Django docs fortement recommandé de ne pas utiliser les valeurs NULL pour une chaîne basée sur des domaines tels que CharField ou TextField. Lisez la documentation pour l'explication:
https://docs.djangoproject.com/en/dev/ref/models/fields/#null
Solution:
Vous pouvez également la chaîne d'ensemble des méthodes sur QuerySets, je pense. Essayez ceci:
Qui devrait vous donner le jeu que vous cherchez.
De Django 1.8,
Pour éviter les erreurs courantes lors de l'utilisation de
exclude
, rappelez-vous:Vous pouvez pas ajouter plusieurs conditions dans d'exclusion() bloc comme
filter
.Pour exclure plusieurs conditions, vous devez utiliser plusieurs exclure()
Exemple
c'est une autre façon simple de le faire .
None
n'est pas la même chose que""
.Vous pouvez simplement faire ceci:
C'est vraiment aussi simple que cela.
filter
est utilisé pour faire correspondre etexclude
est pour correspondre à tout, mais ce qu'il spécifie. Cela permettrait d'évaluer dans SQL commeNOT alias='' AND alias IS NOT NULL
.alias=""
) et NULLE (alias=None
) alias à partir de la requête. Vôtre serait d'inclure des instances avecName(alias=None)
..filter(alias!="")
mais pas le titre. J'ai édité ma réponse. Cependant, des champs de caractère ne devrait pas autoriser les valeurs NULL et utilisez la chaîne vide pour une non-valeur (par convention).