3

I have a query and i want to exclude null companies as well as specific user email.

Demo.objects.all().exclude(company__isnull=True, email="abc@gmail.com")

but seems like above exclude does not work with multiple arguments, my return queryset has email="abc@gmail.com" in it.

If i try above query with single arguments, it works. but not working with multiple arguments. Anyone has any idea how to pass multiple arguments in django exclude ?

Thanks

3 Answers3

7

You can do this, but then you say exclude all Demos that have company__isnull=True, and as email 'abc@gmail.com'. This thus means that if only one of the two conditions is met, it is not excluded.

You can work with Q objects, like:

from django.db.models import Q

Demo.objects.exclude(
    Q(company__isnull=True) |
    Q(email='abc@gmail.com')
)

But it is likely more readable with:

Demo.objects.exclude(
    company__isnull=True
).exclude(
    email='abc@gmail.com'
)

this will thus exclude items for which company is NULL and exclude items for which email is 'abc@gmail.com'. So here we exclude it from the moment at least one condition is satisfied.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
1

Queries are lazy, nothing happens until you try to pull data from it, so there's no downside to using .exclude() more than once.

Demo.objects.exclude(
    company__isnull=True
).exclude(
    email='abc@gmail.com'
)

Another way is to use Q objects that can be combined using the & and | operators.

# Import
from django.db.models import Q

# Exclude query
exclude_query = Q()
exclude_query.add((~Q(company__isnull=True), Q.OR)
exclude_query.add((~Q(email="abc@gmail.com"), Q.OR)

# Get final objects which excludes email "abc@gmail.com" and null companys
result = Demo.objects.filter(exclude_query)
ksmehta
  • 61
  • 3
0

Your logic is not right, this is excluding every Demo that has no company and has an email of abc@gmail.com. You may want to chain exclude() calls instead.

Demo.objects.all().exclude(company__isnull=True).exclude(email="abc@gmail.com")
Ahmed I. Elsayed
  • 2,013
  • 2
  • 17
  • 30