In Django Model QuerySets sehe ich, dass es __gt
und __lt
für Vergleichswerte gibt, aber es gibt __ne
/!=
/<>
(nicht gleich?)
Ich möchte mit a ungleich herausfiltern:
Beispiel:
Model:
bool a;
int x;
Ich möchte
results = Model.objects.exclude(a=true, x!=5)
Der !=
ist nicht korrekt. Ich habe __ne
, <>
ausprobiert.
Ich habe folgendes benutzt:
results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
Vielleicht könnte Q Objekte bei diesem Problem hilfreich sein. Ich habe sie nie benutzt, aber es scheint, dass sie annulliert und kombiniert werden können, ähnlich wie normale python Ausdrücke.
Update: Ich habe es gerade ausprobiert, es scheint ziemlich gut zu funktionieren:
>>> 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>, ...]
Ihre Abfrage scheint doppelt negativ zu sein. Sie möchten alle Zeilen ausschließen, in denen x nicht 5 ist. Mit anderen Worten, Sie möchten alle Zeilen einschließen, in denen x IS 5 ist.
results = Model.objects.filter(x=5).exclude(a=true)
Um Ihre spezifische Frage zu beantworten, gibt es kein "nicht gleich", aber das liegt wahrscheinlich daran, dass Django sowohl "Filter" - als auch "Ausschluss" -Methoden zur Verfügung hat, sodass Sie immer nur die logische Runde umschalten können, um das gewünschte Ergebnis zu erhalten .
die Syntax field=value
in Abfragen ist eine Abkürzung für field__exact=value
. Das heißt, dass Django Abfrageoperatoren auf Abfragefelder in den Bezeichnern setzt. Django unterstützt die folgenden Operatoren:
exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex
Ich bin sicher, indem ich diese mit den Q-Objekten kombiniere, wie , schlägt Dave Vogt vor und benutze filter()
oder exclude()
als Jason Baker schlägt vor , dass Sie genau das bekommen, was Sie für nahezu jede mögliche Abfrage benötigen.
Es ist einfach, mit Django 1.7 eine benutzerdefinierte Suche zu erstellen. Es gibt ein __ne
Nachschlagebeispiel in offizielle Django-Dokumentation .
Sie müssen zuerst die Suche selbst erstellen:
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
Dann müssen Sie es registrieren:
from Django.db.models.fields import Field
Field.register_lookup(NotEqual)
Und jetzt können Sie die Suche __ne
in Ihren Abfragen wie folgt verwenden:
results = Model.objects.exclude(a=True, x__ne=5)
In Django 1.9/1.10 gibt es drei Optionen.
results = Model.objects.exclude(a=true).filter(x=5)
Verwenden Sie Q()
objects und den ~
operator
from Django.db.models import Q
object_list = QuerySet.filter(~Q(a=True), x=5)
Registrieren Sie eine benutzerdefinierte Suchfunktion
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
Der register_lookup
-Dekorator wurde in Django 1.8 hinzugefügt und ermöglicht wie gewohnt die benutzerdefinierte Suche:
results = Model.objects.exclude(a=True, x__ne=5)
Bei den Modellen können Sie mit =
, __gt
, __gte
, __lt
, __lte
filtern. Sie können ne
, !=
oder <>
. Mit dem Q-Objekt können Sie jedoch eine bessere Filterung erzielen.
Sie können die Verkettung von QuerySet.filter()
und QuerySet.exlude()
vermeiden und Folgendes verwenden:
from Django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')
exclude()
Der Django Issue Tracker hat den bemerkenswerten Eintrag # 576 mit dem Titel "Queryset hat keinen" ungleichen "Filteroperator" . Es ist bemerkenswert, weil es (ab April 2016) "vor 9 Jahren eröffnet" (in der Django Steinzeit), "vor 4 Jahren geschlossen" und "vor 5 Monaten zuletzt geändert" wurde.
Lesen Sie die Diskussion durch, es ist interessant. Grundsätzlich argumentieren einige Leute, dass __ne
hinzugefügt werden sollte, während andere sagen, dass exclude()
klarer ist, und daher __ne
sollte nicht hinzugefügt werden.
(Ich stimme dem ersteren zu, da das letztere Argument in etwa der Aussage entspricht, dass Python nicht !=
haben sollte, weil es ==
und not
bereits hat ...)
Sie sollten filter
und exclude
so verwenden
results = Model.objects.exclude(a=true).filter(x=5)
Mit ausschließen und filtern
results = Model.objects.filter(x=5).exclude(a=true)
Das letzte Codebit schließt alle Objekte aus, bei denen x! = 5 und a True ist. Versuche dies:
results = Model.objects.filter(a=False, x=5)
Denken Sie daran, dass das = -Zeichen in der obigen Zeile dem Parameter a Falsch und dem Parameter x die Zahl 5 zuweist. Es prüft nicht auf Gleichheit. Daher gibt es keine Möglichkeit, das Symbol! = In einem Abfrageaufruf zu verwenden.
Was Sie suchen, sind alle Objekte, die entweder a=false
oderx=5
haben. In Django dient |
als OR
Operator zwischen Abfragesätzen:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
results = Model.objects.filter (a = True) .exclude (x = 5)
wählen Sie * aus tablex mit a! = 0 und x! = 5
Django-Modell-Werte (Offenlegung: Autor) liefert eine Implementierung des NotEqual -Nachschlages, wie in diese Antwort . Es bietet auch syntaktische Unterstützung dafür:
from model_values import F
Model.objects.exclude(F.x != 5, a=True)
Achten Sie auf viele falsche Antworten auf diese Frage!
Die Logik von Gerard ist korrekt, es wird jedoch eher eine Liste als ein Abfragesatz zurückgegeben (was möglicherweise keine Rolle spielt).
Wenn Sie einen Abfragesatz benötigen, verwenden Sie Q:
from Django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))