Frage

In Django Model Querysets sehe ich, dass es eine gibt __gt und __lt Für Vergleichswerte, gibt es aber a __ne/!=/<> (nicht gleich?)

Ich möchte mit einem nicht gleichwertigen herausfiltern:

Beispiel:

Model:
    bool a;
    int x;

Ich will

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

Das != ist keine korrekte Syntax. Ich habe es versucht __ne, <>.

Am Ende verwendete ich:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)
War es hilfreich?

Lösung

Vielleicht Q Objekte könnte für dieses Problem hilfreich sein. Ich habe sie nie benutzt, aber es scheint, dass sie negiert und ähnlich wie normale Python -Ausdrücke kombiniert werden können.

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>, ...]

Andere Tipps

Ihre Abfrage scheint ein doppeltes Negativ zu haben. Sie möchten alle Zeilen ausschließen, in denen X nicht 5 ist. Mit anderen Worten, Sie möchten alle Zeilen einbeziehen, in denen X 5 ist. Ich glaube, dies wird den Trick tun.

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 "ausschließen" Methoden zur Verfügung hat, damit Sie immer die Logikrunde wechseln können, um das gewünschte Ergebnis zu erzielen.

das field=value Syntax in Abfragen ist eine Abkürzung für field__exact=value. Das heißt das Django stellt Abfragebetreiber auf Abfragefelder in die Kennungen ein. Django unterstützt die folgenden Betreiber:

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 mir sicher, indem ich diese mit den Q -Objekten kombiniere als Dave Vogt schlägt vor und verwenden filter() oder exclude() wie Jason Baker schlägt vor Sie erhalten genau das, was Sie für eine mögliche Abfrage benötigen.

Es ist einfach, mit Django 1.7 einen benutzerdefinierten Lookup zu erstellen. Dort ist ein __ne Suchbeispiel in Django Offizielle 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 verwenden __ne Suchen Sie in Ihren Abfragen wie folgt:

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

Im Django 1.9/1.10 Es gibt drei Optionen.

  1. Kette exclude und filter

    results = Model.objects.exclude(a=true).filter(x=5)
    
  2. Verwenden Q() Objekte und die ~ Operator

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
  3. Registrieren a 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
    

    Das register_lookup Dekorateur wurde hinzugefügt in Django 1.8 und ermöglicht eine benutzerdefinierte Suche wie gewohnt:

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

Während der Modelle können Sie mit filtern =, __gt, __gte, __lt, __lte, Sie können nicht verwenden ne, != oder <>. Sie können jedoch eine bessere Filterung bei der Verwendung des Q -Objekts erreichen.

Sie können es vermeiden, zu werden QuerySet.filter() und QuerySet.exlude(), und verwenden Sie dies:

from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')

Ausstehende Entwurfsentscheidung. In der Zwischenzeit verwenden Sie exclude()

Der Django -Ausgabe -Tracker hat das bemerkenswerte Eintrag Nr. 5763, mit dem Titel "QuerySet hat keinen" nicht gleichen "Filteroperator". Es ist bemerkenswert, weil es (ab April 2016) "vor 9 Jahren eröffnet wurde" (in der Django Stone Age), "vor 4 Jahren geschlossen" und "Letzte vor 5 Monaten".

Lesen Sie die Diskussion durch, es ist interessant. Grundsätzlich argumentieren einige Leute __ne sollte hinzugefügt werden, während andere sagen exclude() ist klarer und daher __nesollte nicht hinzugefügt werden.

(Ich stimme erstere zu, weil das letztere Argument ungefähr gleichbedeutend mit der Aussage von Python ist != Weil es hat == und not schon...)

Du solltest benutzen filter und exclude so was

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

Verwenden von Ausschluss und Filter

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

Das letzte Stück Code schließt alle Objekte aus, bei denen x! = 5 und a wahr sind. Versuche dies:

results = Model.objects.filter(a=False, x=5)

Denken Sie daran, dass das = in der obigen Zeile dem Parameter A und der Nummer 5 dem Parameter x False zugewiesen wird. Es geht nicht um Gleichheit. Daher gibt es also keine Möglichkeit, das Symbol in einem Abfrageanruf zu verwenden.

Was Sie suchen, sind alle Objekte, die entweder haben a=false oder x=5. In Django, | dient als OR Bediener zwischen QuerySets:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)

results = Model.objects.filter(a = True).exclude(x = 5)
Generiert diese SQL:
select * from tablex where a != 0 and x !=5
Das SQL hängt davon ab, wie Ihr wahres/falsches Feld dargestellt wird, und der Datenbankmotor. Der Django -Code ist alles, was Sie brauchen.

Django-model-values (disclosure: author) provides an implementation of the NotEqual lookup, as in this answer. It also provides syntactic support for it:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)

Watch out for lots of incorrect answers to this question!

Gerard's logic is correct, though it will return a list rather than a queryset (which might not matter).

If you need a queryset, use Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top