979 Stimmen

Wie tue ich ein nicht gleich in Django Queryset Filterung?

In Django Modell QuerySets, ich sehe, dass es eine __gt y __lt für Vergleichswerte, aber gibt es eine __ne o != ( nicht gleich )? Ich möchte mit einem "nicht gleich" herausfiltern. Zum Beispiel, für

Model:
    bool a;
    int x;

Ich möchte Folgendes tun

results = Model.objects.exclude(a=True, x!=5)

El != ist keine korrekte Syntax. Ich habe auch versucht __ne .

Ich habe es schließlich benutzt:

results = Model.objects.exclude(a=True, x__lt=5).exclude(a=True, x__gt=5)

1094voto

Dave Vogt Punkte 16300

Sie können verwenden Q Objekte für diese. Sie können mit der Option ~ Operator und kombiniert ähnlich wie normale Python-Ausdrücke:

from myapp.models import Entry
from django.db.models import Q

Entry.objects.filter(~Q(id=3))

gibt alle Einträge zurück, mit Ausnahme der Einträge mit 3 als ihre ID:

[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]

805voto

d4nt Punkte 14749

Ihre Abfrage scheint eine doppelte Verneinung zu haben, Sie wollen alle Zeilen ausschließen, in denen x nicht 5 ist, d.h. Sie wollen alle Zeilen einschließen, in denen x est 5. Ich glaube, das wird genügen:

results = Model.objects.filter(x=5).exclude(a=True)

Um Ihre konkrete Frage zu beantworten: Es gibt kein "nicht gleich". Feldsuche aber das liegt wahrscheinlich daran, dass Django beides hat filter y exclude Methoden zur Verfügung, so dass Sie die Logik immer einfach umstellen können, um das gewünschte Ergebnis zu erhalten.

170voto

El field=value Syntax in Abfragen ist eine Kurzform für field__exact=value . Dies bedeutet, dass Django setzt Abfrageoperatoren auf Abfragefelder in den Bezeichnern . Django unterstützt die folgenden Operatoren:

exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range

date
year
iso_year
month
day
week
week_day
iso_week_day
quarter
time
hour
minute
second

isnull
regex
iregex

Ich bin sicher, dass durch die Kombination mit den Q-Objekten als Dave Vogt schlägt vor und mit filter() o exclude() als Jason Baker schlägt vor erhalten Sie genau das, was Sie für fast alle möglichen Fragen benötigen.

162voto

ilse2005 Punkte 10487

Es gibt drei Möglichkeiten:

  1. Kette exclude y filter

    results = Model.objects.exclude(a=True).filter(x=5)
  2. Utilice Q() objetos und die ~ Betreiber

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
  3. Einschreiben benutzerdefinierte Lookup-Funktion

    from django.db.models import Lookup
    from django.db.models 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

    Diese können dann wie gewohnt verwendet werden:

    results = Model.objects.exclude(a=True, x__ne=5)

121voto

Dmitrii Mikhailov Punkte 4767

Es ist einfach, eine benutzerdefinierte Suche zu erstellen, es gibt eine __ne Nachschlagebeispiel in Die offizielle Dokumentation von Django .

Sie müssen zuerst die Suche selbst erstellen:

from django.db.models import 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

Dann müssen Sie es registrieren:

from django.db.models import Field
Field.register_lookup(NotEqual)

Und jetzt können Sie die __ne Lookup in Ihren Abfragen wie folgt:

results = Model.objects.exclude(a=True, x__ne=5)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X