Question

Is there a way to do a query and exclude a list of things, instead of calling exclude multiple times?

Was it helpful?

Solution

Based on your reply to Ned, it sounds like you just want to exclude a list of tags. So you could just use the in filter:

names_to_exclude = [o.name for o in objects_to_exclude] 
Foo.objects.exclude(name__in=names_to_exclude)

Does that do what you want?

OTHER TIPS

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

You can do it pretty easily with the Q object:

from django.db.models import Q

excludes = None
for tag in ignored_tags:
    q = Q(tag=tag)
    excludes = (excludes and (excludes | q)) or q # makes sure excludes is set properly
set_minus_excluded = Foo.objects.exclude(excludes)

You should also be able to do it dynamically with exclude():

qs = Foo.objects.all()
for tag in ignored_tags:
    qs = qs.exclude(tag=tag)

To improve on Daniel Roseman's answer I think it would be better to get the values you need directly from the queryset instead of the for loop that could be expensive on large data sets i.e.

names_to_exclude = objects_to_exclude.values_list('name')
Foo.objects.exclude(name__in=names_to_exclude)

You can try this also.

exclude_list = ['A', 'B', 'C'] qs = Foo.objects.exclude(items__in=exclude_list)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top