views:

125

answers:

3
+2  Q: 

multiple exclude

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

+1  A: 

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.

Ned Batchelder
I have a model that has a tags manytomany field. the user can have a large amount of ignore tags. I want to dynamically exclude the objects that the user doesn't want to see. I won't know how many times to call exclude till run time.
Johnd
+1  A: 

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)
tghw
+3  A: 

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?

Daniel Roseman
I do it with a list of objects_to_exclude directly, I don't use the o.name:ignore_tags = request.user.ignore_tags.all()case_list = Case.objects.exclude(tags__in = ignore_tags))
Johnd