Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django excluding specific instances from queryset without using field lookup

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:

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)

like image 605
Agos Avatar asked Jun 13 '10 11:06

Agos


People also ask

How do I exclude an object in QuerySet?

To exclude multiple objects from a queryset, we will use the exclude() methed along with in filter. And then assign the queryset names which you have to exclude in the variable named “a”.

Can I filter a QuerySet Django?

Working with Filter Easily the most important method when working with Django models and the underlying QuerySets is the filter() method, which allows you to generate a QuerySet of objects that match a particular set of filtered parameters.

How do I do a not equal in Django QuerySet filtering?

To answer your specific question, there is no "not equal to" but that's probably because django has both "filter" and "exclude" methods available so you can always just switch the logic round to get the desired result.

Which can be used to retrieve an object directly instead of a QuerySet?

Retrieving Single Objects from QuerySets We can do this using the get() method. The get() returns the single object directly. Let's see the following example. As we can see in both examples, we get the single object not a queryset of a single object.


2 Answers

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>])

like image 138
obeattie Avatar answered Sep 20 '22 19:09

obeattie


The Given answer is perfect and try this which works fine for me

step 1)

 from django.db.models import Q 

step 2)

 MyModel.objects.filter(~Q(id__in=[o.id for o in <unwanted objects>])) 
like image 26
kartheek Avatar answered Sep 18 '22 19:09

kartheek