Réponses:
Vous pouvez faire ceci:
Name.objects.exclude(alias__isnull=True)
Si vous devez exclure des valeurs nulles et des chaînes vides, la façon préférée de le faire est de chaîner les conditions comme ceci:
Name.objects.exclude(alias__isnull=True).exclude(alias__exact='')
Le chaînage de ces méthodes vérifie fondamentalement chaque condition indépendamment: dans l'exemple ci-dessus, nous excluons les lignes où alias
est nul ou une chaîne vide, de sorte que vous obtenez tous les Name
objets qui ont un alias
champ non nul, non vide . Le SQL généré ressemblerait à quelque chose comme:
SELECT * FROM Name WHERE alias IS NOT NULL AND alias != ""
Vous pouvez également passer plusieurs arguments à un seul appel à exclude
, ce qui garantirait que seuls les objets répondant à toutes les conditions sont exclus:
Name.objects.exclude(some_field=True, other_field=True)
Ici, les lignes dans lesquelles some_field
et other_field
sont vraies sont exclues, nous obtenons donc toutes les lignes où les deux champs ne sont pas vrais. Le code SQL généré ressemblerait un peu à ceci:
SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE)
Alternativement, si votre logique est plus complexe que cela, vous pouvez utiliser les objets Q de Django :
from django.db.models import Q
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact=''))
Pour plus d'informations, consultez cette page et cette page dans la documentation Django.
En passant: Mes exemples SQL ne sont qu'une analogie - le code SQL généré sera probablement différent. Vous aurez une meilleure compréhension du fonctionnement des requêtes Django en regardant réellement le SQL qu'elles génèrent.
OR
pour fusionner les conditions. Je vais modifier ma réponse pour clarifier.
NOT (A AND B)
est équivalent à NOT A OR NOT B
. Je pense que cela rend les choses déroutantes pour les nouveaux développeurs de Django qui connaissent le SQL mais ne connaissent pas les ORM.
AND
dans la première requête en un OR
parce que vous utilisez exclude
. Dans le cas général, il est probablement plus correct de considérer le chaînage comme un THEN
, c'est-à-dire exclude(A) THEN exclude(B)
. Désolé pour le langage dur ci-dessus. Votre réponse est vraiment bonne, mais je crains que les nouveaux développeurs ne prennent votre réponse trop généralement.
AND
et OR
pourrait être utile pour quelqu'un venant à Django depuis un arrière-plan SQL. Pour une compréhension plus approfondie de Django, je pense que les documents font un meilleur travail que moi.
Name.objects.filter(alias__gt='',alias__isnull=False)
alias__isnull=False
condition est redondante. Si le champ l'est Null
sûrement, il sera exclu par la première clause?
alias__gt
était la seule chose qui fonctionnait pour les colonnes de type JSON où je voulais exclure les chaînes vides de JSON comme {'something:''}
. La syntaxe de travail est donc:jsoncolumnname__something__gt=''
Premièrement, les documents Django recommandent fortement de ne pas utiliser de valeurs NULL pour les champs basés sur des chaînes tels que CharField ou TextField. Lisez la documentation pour l'explication:
https://docs.djangoproject.com/en/dev/ref/models/fields/#null
Solution: Je pense que vous pouvez également enchaîner des méthodes sur QuerySets. Essaye ça:
Name.objects.exclude(alias__isnull=True).exclude(alias="")
Cela devrait vous donner l'ensemble que vous recherchez.
Depuis Django 1.8,
from django.db.models.functions import Length
Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)
Pour éviter les erreurs courantes lors de l'utilisation exclude
, n'oubliez pas:
Vous ne pouvez pas ajouter plusieurs conditions dans un bloc exclude () comme filter
. Pour exclure plusieurs conditions, vous devez utiliser plusieurs exclude ()
Exemple
Incorrect :
User.objects.filter (email='example@example.com '). Exclude (profile__nick_name =' ', profile__avt =' ')
Correct :
User.objects.filter (email='example@example.com '). Exclude (profile__nick_name =' '). Exclude (profile__avt =' ')
Vous pouvez simplement faire ceci:
Name.objects.exclude(alias="").exclude(alias=None)
C'est vraiment aussi simple que cela. filter
est utilisé pour faire correspondre et exclude
pour faire correspondre tout sauf ce qu'il spécifie. Cela serait évalué en SQL comme NOT alias='' AND alias IS NOT NULL
.
alias=""
) et NULL ( alias=None
) de la requête. Le vôtre inclurait des instances avec Name(alias=None)
.
.filter(alias!="")
mais pas au titre. J'ai édité ma réponse. Cependant, les champs de caractères ne doivent pas autoriser les valeurs NULL et utiliser la chaîne vide pour une non-valeur (selon la convention).
c'est une autre façon simple de le faire.
Name.objects.exclude(alias=None)
None
n'est pas la même chose que ""
.
OR
(uniquement dans ce cas), il produit un SQLAND
. Voir cette page pour référence: docs.djangoproject.com/en/dev/topics/db/queries/… L'avantage du chaînage est que vous pouvez mélangerexclude
etfilter
modéliser des conditions de requête compliquées. Si vous souhaitez modéliser un vrai SQL,OR
vous devez utiliser un objet Django Q: docs.djangoproject.com/en/dev/topics/db/queries/… Veuillez modifier votre modification pour refléter cela, car la réponse est gravement trompeuse en l'état .