Dans Django modèle QuerySets, je vois qu'il existe un __gt
et __lt
pour les valeurs comparatives, mais il y a un __ne
/!=
/<>
(pas égal?)
Je veux filtrer en utilisant un pas égal:
Exemple:
Model:
bool a;
int x;
Je voudrais
results = Model.objects.exclude(a=true, x!=5)
Le !=
n'est pas une 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)
Peut-être que objets Q pourrait aider à résoudre ce problème. Je ne les ai jamais utilisées, mais il semble qu'elles puissent être annulées et combinées un peu comme les expressions python normales.
Mise à jour: Je viens d'essayer, cela semble assez bien fonctionner:
>>> from myapp.models import Entry
>>> from Django.db.models import Q
>>> Entry.objects.filter(~Q(id = 3))
[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]
Votre requête semble avoir un double négatif, vous voulez exclure toutes les lignes où x n'est pas 5, donc vous voulez inclure toutes les lignes où x IS 5. Je pense que cela fera l'affaire.
results = Model.objects.filter(x=5).exclude(a=true)
Pour répondre à votre question spécifique, il n'y a pas de "différent de", mais c'est probablement parce que Django dispose des méthodes "filter" et "exclude". Vous pouvez donc toujours changer de logique pour obtenir le résultat souhaité. .
la syntaxe field=value
dans les requêtes est un raccourci pour field__exact=value
. C'est-à-dire que Django place des opérateurs de requête sur les champs de requête dans les identifiants . Django prend en charge les opérateurs suivants:
exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex
Je suis sûr qu'en combinant ces objets avec les objets Q comme Dave Vogt le suggère et en utilisant filter()
ou exclude()
comme Jason Baker suggère vous obtiendrez exactement ce dont vous avez besoin pour toutes les requêtes possibles.
Il est facile de créer une recherche personnalisée avec Django 1.7. Il existe un exemple de recherche __ne
dans documentation officielle de Django .
Vous devez d'abord créer la recherche elle-même:
from Django.db.models import Lookup
class NotEqual(Lookup):
lookup_name = 'ne'
def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
params = lhs_params + rhs_params
return '%s <> %s' % (lhs, rhs), params
Ensuite, vous devez l'enregistrer:
from Django.db.models.fields import Field
Field.register_lookup(NotEqual)
Et maintenant, vous pouvez utiliser la recherche __ne
dans vos requêtes, comme ceci:
results = Model.objects.exclude(a=True, x__ne=5)
Dans Django 1.9/1.10 , il y a trois options.
_results = Model.objects.exclude(a=true).filter(x=5)
_
Utilisez Q()
objets et l'opérateur ~
_from Django.db.models import Q
object_list = QuerySet.filter(~Q(a=True), x=5)
_
Enregistrer une fonction de recherche personnalisée
_from Django.db.models import Lookup
from Django.db.models.fields import Field
@Field.register_lookup
class NotEqual(Lookup):
lookup_name = 'ne'
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s <> %s' % (lhs, rhs), params
_
Le décorateur _register_lookup
_ a été ajouté dans Django 1.8 et permet une recherche personnalisée comme d'habitude:
_results = Model.objects.exclude(a=True, x__ne=5)
_
Alors qu'avec les modèles, vous pouvez filtrer avec =
, __gt
, __gte
, __lt
, __lte
, vous ne pouvez pas utiliser ne
, !=
ou <>
. Cependant, vous pouvez obtenir un meilleur filtrage en utilisant l'objet Q.
Vous pouvez éviter d'enchaîner QuerySet.filter()
et QuerySet.exlude()
, et utilisez ceci:
from Django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')
exclude()
Le suivi de la question Django a le remarquable entrée # 576 , intitulé "Queryset n'a pas d'opérateur de filtre" non égal "" . Il est remarquable car (à partir d'avril 2016), il a été "ouvert il y a 9 ans" (à l'époque deDjango Pierre), "fermé il y a 4 ans" et "modifié pour la dernière fois il y a 5 mois".
Lisez la discussion, c'est intéressant. Fondamentalement, certaines personnes soutiennent que __ne
devrait être ajouté, tandis que d'autres disent que exclude()
est plus clair et donc __ne
ne devrait pas être ajouté.
(Je suis d'accord avec le premier, parce que le dernier argument est à peu près équivalent à dire que Python ne devrait pas avoir !=
car il contient ==
et not
déjà ...)
Vous devriez utiliser filter
et exclude
comme ceci
results = Model.objects.exclude(a=true).filter(x=5)
Utiliser exclure et filtrer
results = Model.objects.filter(x=5).exclude(a=true)
Le dernier bit de code exclura tous les objets où x! = 5 et a est True. Essaye ça:
results = Model.objects.filter(a=False, x=5)
N'oubliez pas que le signe = dans la ligne ci-dessus affecte False au paramètre a et le nombre 5 au paramètre x. Ce n'est pas vérifier l'égalité. Ainsi, il n’ya vraiment aucun moyen d’utiliser le symbole! = Dans un appel de requête.
Ce que vous recherchez, ce sont tous les objets qui ont soit a=false
ox=5
. Dans Django, |
sert d’opérateur OR
entre les ensembles de requêtes:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
results = Model.objects.filter (a = True) .exclude (x = 5)
sélectionnez * de tablex où a! = 0 et x! = 5
Django-model-values (divulgation: auteur) fournit une implémentation de la recherche NotEqual , comme dans cette réponse . Il fournit également un support syntaxique pour cela:
from model_values import F
Model.objects.exclude(F.x != 5, a=True)
Méfiez-vous des tas de réponses incorrectes à cette question!
La logique de Gerard est correcte, bien qu'elle renvoie une liste plutôt qu'un ensemble de requêtes (ce qui peut ne pas être important).
Si vous avez besoin d'un queryset, utilisez Q:
from Django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))