web-dev-qa-db-ja.com

DjangoクエリセットでOR条件を実行するには?

このSQLクエリと同等のDjangoクエリを書きたい:

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

Djangoクエリセットフィルターの作成方法

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

ANDsフィルターであるため、これは機能しません。フィルターをORして、個々のクエリセットの結合を取得します。

244
Elisa
from Django.db.models import Q
User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))

ドキュメンテーション経由

470
Lakshman Prasad

QuerySets implements Python __or__演算子(|)、またはunionであるため、動作します。ご想像のとおり、|バイナリ演算子はQuerySetを返すため、order_by().distinct()、およびその他のクエリセットフィルターを最後に追加できます。

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

両方のオプションは、既存の回答ですでに言及されています:

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

そして

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

ただし、どちらを優先するかに関しては混乱が生じているようです。

ポイントは、これらはSQLレベルで同一であるため、好きなものを自由に選んでください!

Django ORM Cookbook は、これについてある程度詳しく説明しています。関連する部分を次に示します。


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

につながる

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%)'

そして

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

につながる

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%)'

ソース: Django-orm-cookbook


1
jojo