Comment dois-je faire un pas égal dans Django queryset de filtrage?
Dans Django modèle QuerySets, je vois qu'il y a un __gt
et __lt
pour comparative des valeurs, mais est-il une __ne
/!=
/<>
(pas égale?)
Je veux filtrer à l'aide d'un pas égal:
Exemple:
Model:
bool a;
int x;
Je veux
results = Model.objects.exclude(a=true, x!=5)
La !=
n'est pas la syntaxe correcte. J'ai essayé __ne
, <>
.
J'ai fini par utiliser:
results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
- Aurait résultats = Modèle.objets.exclure(a=vrai).filtre(x=5) ont travaillé?
- Pas de. Votre requête exclut tous les
a=true
d'abord, puis applique lax=5
filtre sur le reste. Le but de la requête nécessaire seulement ceux aveca=true
etx!=5
. La différence étant que tous ceux aveca=true
etx=5
sont également filtrés.
Vous devez vous connecter pour publier un commentaire.
Peut-être Q objets pourrait être de l'aide pour ce problème. Je n'ai jamais utilisé, mais il semble qu'ils peuvent être réduites à néant et combiné comme normale des expressions python.
Mise à jour: j'ai Juste essayé, il semble fonctionner assez bien:
Votre requête semble avoir un double négatif, vous souhaitez exclure toutes les lignes où x n'est pas un 5, en d'autres mots que vous souhaitez inclure toutes les lignes où x EST 5. Je crois que ça va faire l'affaire.
Pour répondre à votre question précise, il n'existe pas "n'est pas égal à" mais c'est probablement parce que django a deux "filtre" et "exclure" les méthodes disponibles de sorte que vous pouvez toujours basculer la logique ronde pour obtenir le résultat souhaité.
results = Model.objects.filter(a=true).exclude(x=5)
objects.exclude(**filter1).filter(**filter2)
donne des résultats différents deobjects.filter(**filter1).exclude(**filter2)
, tandis que ~Q obtiendrez toujours correcte de la négation à l'intérieur deobjects.filter(**filter_with_Q)
exclude
etfilter
des appels à ne pas faire de différence significative. L'ordre des conditions dans leWHERE
clause de changements, mais comment est-ce que la matière?la
field=value
la syntaxe des requêtes est un raccourci pourfield__exact=value
. C'est-à-dire que Django met opérateurs de requête sur les champs de requête dans les identificateurs. Django prend en charge les opérateurs suivants:Je suis sûr que par la combinaison de ces derniers avec les objets Q comme Dave Vogt suggère et à l'aide de
filter()
ouexclude()
comme Jason Baker suggère vous obtiendrez exactement ce que vous avez besoin pour n'importe quelle requête.tg=Tag.objects.filter(user=request.user).exclude(name__regex=r'^(public|url)$')
et il fonctionne.icontains
,iexact
et similaire signifie "ignorer la casse". Ce n'est pas pour "inverse".exclude()
avec plusieurs termes, vous pouvez composer de la proposition avec lesOR
de l'opérateur, par exempleexclude(Q(field1__queryop1=value1) | Q(field2__queryop2=value2))
afin d'exclure les résultats dans les deux conditions.Il est facile de créer un personnalisé de recherche avec Django 1.7. Il y a un
__ne
de recherche exemple dans Django documentation officielle.Vous avez besoin pour créer la recherche elle-même d'abord:
Ensuite, vous devez l'enregistrer:
Et maintenant, vous pouvez utiliser le
__ne
de recherche de vos requêtes comme ceci:Dans Django 1.9/1.10 il y a trois options.
De la chaîne
exclure
etfiltre
Utilisation
Q()
objets et la~
de l'opérateurEnregistrer un fonction de recherche personnalisée
La
register_lookup
décorateur a été ajouté dans Django 1.8 etpermet personnalisé de recherche comme d'habitude:
Alors qu'avec les Modèles, vous pourrez filtrer avec
=
,__gt
,__gte
,__lt
,__lte
, vous ne pouvez pas utiliserne
,!=
ou<>
. Cependant, vous pouvez réaliser un meilleur filtrage à l'aide de la Q objet.Vous pouvez éviter le chaînage
QuerySet.filter()
etQuerySet.exlude()
, et de l'utiliser:En attente de décision de conception. Pendant ce temps, l'utilisation
exclude()
Le Django issue tracker a la remarquable entrée #5763,
intitulé "Queryset ne pas avoir un "pas égal" opérateur de filtre".
Il est remarquable que (dès avril 2016), il a été
"a ouvert il y a 9 ans" (dans le Django de l'âge de pierre),
"fermé il y a 4 ans", et
"dernière modification le il y a 5 mois".
Lire par le biais de la discussion, il est intéressant.
Fondamentalement, certaines personnes affirment
__ne
doit être ajoutéalors que d'autres disent
exclude()
est plus clair et donc__ne
devrait pas être ajouté.
(Je suis d'accord avec l'ancien, parce que le dernier argument est
à peu près équivalent à dire que Python ne devrait pas avoir
!=
parce queil a
==
etnot
déjà...)Vous devez utiliser
filter
etexclude
comme ceÀ l'aide d'exclusion et de filtre
Le dernier bit de code, d'exclure tous les objets où x!=5 et a est Vrai. Essayez ceci:
Rappelez-vous, le signe = dans la ligne ci-dessus est d'attribuer des Faux pour le paramètre a et le numéro 5 pour le paramètre "x". Ce n'est pas la vérification de l'égalité. Ainsi, il n'est pas vraiment possible d'utiliser la != symbole de dans une requête d'appel.
results = Model.objects.filter(a__in=[False,None],x=5)
Ce que vous cherchez sont tous les objets qui ont
a=false
oux=5
. Dans Django,|
sertOR
opérateur entre querysets:Generetes ce sql:
sql dépend de la façon dont votre Vrai/Faux champ est représenté, et le moteur de base de données. Le django code est tout ce que vous devez bien.
Django-modèle-valeurs (divulgation: l'auteur) fournit une mise en œuvre de la NotEqual de recherche, comme dans cette réponse. Il fournit également syntaxique support:
Watch out pour beaucoup de mauvaises réponses à cette question!
Gerard logique est correcte, mais il sera de retour une liste plutôt qu'un queryset (ce qui n'a pas d'importance).
Si vous avez besoin d'un queryset, utilisez Q: