Wie mache ich ein gleiches Django-Quaryset-Filter?

In Django-Modell QuerySets sehe ich, dass es ein __gt und __lt für Vergleichswerte gibt, aber gibt es ein __ne / != / <> ( Nicht gleich ?)

Ich möchte herausfiltern mit einem nicht gleich:

  • 2 Formulare, 1 Ansicht, 2 SQL Tabellen in Django
  • Was ist der beste Weg, um auf gespeicherte Prozeduren in Djangos ORM zuzugreifen
  • Django viele-to-may: wie bekomme Zeilen-ID in verwandter Tabelle
  • Django - Verwenden Sie ein Template-Tag innerhalb eines Template-Tags?
  • Führen Sie jinja2 template_filter auf jede Anfrage mit Flask
  • Wie kann man die Abschreibungswarnungen in Django unterdrücken?
  • Beispiel:

     Model: bool a; int x; 

    Ich will

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

    Die != ist nicht korrekte Syntax. Ich habe versucht __ne , <> .

    Ich landete mit:

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

    11 Solutions collect form web for “Wie mache ich ein gleiches Django-Quaryset-Filter?”

    Vielleicht könnten Q-Objekte für dieses Problem hilfreich sein. Ich habe sie nie benutzt, aber es scheint, dass sie negiert 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 ein doppeltes negatives zu haben, Sie möchten alle Zeilen ausschließen, in denen x nicht 5 ist, also mit anderen Worten, Sie möchten alle Zeilen mit x IS 5 enthalten. Ich glaube, das wird den Trick machen.

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

    Um Ihre spezifische Frage zu beantworten, gibt es kein "nicht gleich", aber das ist wahrscheinlich, weil django sowohl "Filter" und "ausschließen" Methoden zur Verfügung hat, so dass man immer nur die Logik umschalten kann, um das gewünschte Ergebnis zu erhalten.

    Das field=value Syntax 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 folgende 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 Dave Vogt vorschlägt und mit filter() oder exclude() wie Jason Baker vorschlägt, dass du genau das bekommst, was du für fast jede mögliche Abfrage benötigst.

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

    Sie können die QuerySet.filter() und QuerySet.exlude() vermeiden und verwenden Sie diese:

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

    Es ist einfach, einen benutzerdefinierten Lookup mit Django 1.7 zu erstellen. Es gibt ein __ne Lookup Beispiel in Django offizielle Dokumentation .

    Du musst 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 kannst du das __ne Lookup in deinen Fragen wie __ne :

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

    In Django 1.9 / 1.10 gibt es drei Möglichkeiten.

    1. Kette exclude und filter

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

       from django.db.models import Q object_list = QuerySet.filter(~Q(a=True), x=5) 
    3. 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 Dekorateur wurde in Django 1.8 hinzugefügt und ermöglicht benutzerdefinierte Suche wie gewohnt:

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

    Sie sollten filter und so exclude

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

    Das letzte Bit des Codes schließt alle Objekte aus, wobei x! = 5 und a wahr ist. Versuche dies:

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

    Denken Sie daran, dass das Zeichen in der obigen Zeile False dem Parameter a und der Nummer 5 zum Parameter x zuweist. Es ist nicht auf Gleichheit zu prüfen. So gibt es eigentlich keine Möglichkeit, das! = Symbol in einem Abfrageaufruf zu verwenden.

    Ausstehende Designentscheidung Mittlerweile exclude()

    Der Django Issue Tracker hat den bemerkenswerten Eintrag # 5763 mit dem Titel "Queryset hat keinen" nicht gleich "Filteroperator" . Es ist bemerkenswert, weil (ab April 2016) es "vor 9 Jahren eröffnet" wurde (in der Django-Steinzeit), "vor 4 Jahren geschlossen" und "zuletzt geändert vor 5 Monaten".

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

    (Ich stimme dem ersteren zu, denn das letztere Argument ist ungefähr gleichbedeutend mit dem Sprechen, dass Python nicht haben sollte != Weil es == und not schon … hat)

    Was du suchst, sind alle Objekte, die entweder a=false oder x=5 . In Django, | Dient als OR Operator zwischen querysets:

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

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

    Generiert diese sql:

      Select * von tablex mit a! = 0 und x! = 5 

    Die sql hängt davon ab, wie Ihr True / False-Feld dargestellt wird, und die Datenbank-Engine. Der Django-Code ist alles was du brauchst.

    Python ist die beste Programmiersprache der Welt.