How to perform OR condition in django queryset?

前端 未结 4 1789
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-07 07:39

I want to write a Django query equivalent to this SQL query:

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

How to construct

相关标签:
4条回答
  • 2020-12-07 08:03

    Just adding this for multiple filters attaching to Q object, if someone might be looking to it. If a Q object is provided, it must precede the definition of any keyword arguments. Otherwise its an invalid query. You should be careful when doing it.

    an example would be

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

    Here the OR condition and a filter with category of income is taken into account

    0 讨论(0)
  • 2020-12-07 08:04

    Because QuerySets implement the Python __or__ operator (|), or union, it just works. As you'd expect, the | binary operator returns a QuerySet so order_by(), .distinct(), and other queryset filters can be tacked on to the end.

    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: This is now fully documented in the Django 2.1 QuerySet API reference. More historic discussion can be found in DjangoProject ticket #21333.

    0 讨论(0)
  • 2020-12-07 08:13
    from django.db.models import Q
    User.objects.filter(Q(income__gte=5000) | Q(income__isnull=True))
    

    via Documentation

    0 讨论(0)
  • 2020-12-07 08:22

    Both options are already mentioned in the existing answers:

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

    and

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

    However, there seems to be some confusion regarding which one is to prefer.

    The point is that they are identical on the SQL level, so feel free to pick whichever you like!

    The Django ORM Cookbook talks in some detail about this, here is the relevant part:


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

    leads to

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

    and

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

    leads to

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

    source: django-orm-cookbook


    0 讨论(0)
提交回复
热议问题