423 Stimmen

Wie man OR-Bedingung in Django Queryset durchführen?

Ich möchte eine Django-Abfrage schreiben, die dieser SQL-Abfrage entspricht:

SELECT * from user where income >= 5000 or income is NULL.

Wie baut man den Django-Queryset-Filter auf?

User.objects.filter(income__gte=5000, income=0)

Das funktioniert nicht, weil es AND s die Filter. Ich möchte OR die Filter, um eine Vereinigung der einzelnen Abfragesätze zu erhalten.

774voto

lprsd Punkte 80189
from django.db.models import Q
User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))

über Dokumentation

81voto

hobs Punkte 16670

Denn QuerySets implementieren die Python __or__ Betreiber ( | ), oder Gewerkschaft, es funktioniert einfach. Wie zu erwarten, ist die | Binäroperator gibt eine QuerySet also order_by() , .distinct() und andere Queryset-Filter können an das Ende angehängt werden.

combined_queryset = User.objects.filter(income__gte=5000) | User.objects.filter(income__isnull=True)
ordered_queryset = combined_queryset.order_by('-income')

Update 2019-06-20: Dies ist nun vollständig dokumentiert in der Django 2.1 QuerySet API-Referenz . Weitere historische Erörterungen sind zu finden in DjangoProjekt Ticket #21333 .

30voto

jojo Punkte 8953

Beide Optionen sind bereits in den vorhandenen Antworten erwähnt:

from django.db.models import Q
q1 = User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))

et

q2 = User.objects.filter(income__gte=5000) | User.objects.filter(income__isnull=True)

Es scheint jedoch eine gewisse Verwirrung darüber zu herrschen, welche der beiden Möglichkeiten vorzuziehen ist.

Der Punkt ist, dass sie sind auf der SQL-Ebene identisch Sie können sich also aussuchen, was Ihnen gefällt!

Le site Django ORM Kochbuch spricht ausführlich darüber, hier ist der relevante Teil:


queryset = User.objects.filter(
        first_name__startswith='R'
    ) | User.objects.filter(
    last_name__startswith='D'
)

führt zu

In [5]: str(queryset.query)
Out[5]: 'SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login",
"auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name",
"auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff",
"auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"
WHERE ("auth_user"."first_name"::text LIKE R% OR "auth_user"."last_name"::text LIKE D%)'

et

qs = User.objects.filter(Q(first_name__startswith='R') | Q(last_name__startswith='D'))

führt zu

In [9]: str(qs.query)
Out[9]: 'SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login",
 "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name",
  "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff",
  "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user"
  WHERE ("auth_user"."first_name"::text LIKE R% OR "auth_user"."last_name"::text LIKE D%)'

_Quelle: django-orm-kochbuch_


16voto

Faiz Hameed Punkte 390

Ich füge dies nur für mehrere Filter hinzu, die an Q Objekt, wenn jemand darauf schauen könnte. Wenn ein Q Objekt bereitgestellt wird, muss es vor der Definition aller Schlüsselwortargumente stehen. Andernfalls ist es eine ungültige Abfrage. Sie sollten vorsichtig sein, wenn Sie dies tun.

ein Beispiel wäre

from django.db.models import Q
User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True),category='income')

Hier wird die ODER-Bedingung und ein Filter mit der Kategorie des Einkommens berücksichtigt

5voto

prakhar newatia Punkte 91

Um die Bedingungen wie "OR" oder "AND" hinzuzufügen, wie wir sie in Sql-Abfragen verwenden, haben wir diesen Weg als Beispiel

from django.db.models import Q
Poll.objects.get(Q(question__startswith='Who'),Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

dies entspricht der folgenden Sql-Abfrage

SELECT * from polls WHERE question LIKE 'Who%'
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

Ich hoffe, Sie können dies richtig verstehen, dass das "," für den "AND"-Operator und "|" für den "OR"-Operator in Django steht.

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