views:

37

answers:

2

Hi, I sometimes have the need to make sure some instances are excluded from a queryset.
This is the way I do it usually:

unwanted_instance = Mymodel.objects.get(pk=bad_luck_number)
uninteresting_stuff_happens()
my_results = MyModel.objects.exclude(id=unwanted_instance.id)

or, if I have more of them:

my_results = MyModel.objects.exclude(id_in=[uw_in1.id, uw_in2.id, uw_in3.id])

This 'feels' a bit clunky, so I tried if I was lucky:

my_ideally_obtained_results = MyModel.objects.exclude(unwanted_instance)

Which doesn't work. But I read here on SO that a subquery can be used as parameter for exclude.
Am I out of luck? Am I missing some functionality (checked the docs, but didn't find any useful pointer)

A: 

I don't really have an answer to your question, but probably you should change your data model, so you can do something like:

results = MyModel.objects.filter(unwanted=False)
muksie
“unwanted” is not an attribute of my model (or else it would already be there), but rather on some query I want to exclude results (specifically to exclude duplicates in different areas of a page)
Agos
I know 'unwanted' isn't an attribute of your model, but it seems like you find your unwanted objects by looking them up with some query (pk=bad_luck_number) so you probably should try to merge those two queries in one.
muksie
+2  A: 

The way you're already doing it is the best way.

If it's a model-agnostic way of doing this you're looking for, don't forget that you can do query.exclude(pk=instance.pk).

Just as an aside, if Django's ORM had an identity mapper (which it doesn't at present), then you would be able to do something like MyModel.objects.filter(<query>).all().remove(<instance>), but you're out of luck in that regard. The way you're doing it (or the one above) is the best you've got.

Oh, and also you can do much better than that in query with a list comprehension: query.exclude(id__in=[o.id for o in <unwanted objects>])

obeattie