Sven
Sven

Reputation: 1172

Reverse foreign key in filter of QuerySet in Django

Let's say I have two models:

class Human(models.Model):
    name= models.CharField(#...

class Jacket(models.Model):
    owner = models.ForeignKey(Human, #...

So, thanks to this question I was able to figure out that I could get all Jackets of a Human by doing: human_object.jacket_set

Now I want to get a Queryset with all Humans that own a jacket. Inspired by this question, I tried something like this,

Human.objects.exclude(jacket__set=None)

but I wouldn't be here if that had worked.

Upvotes: 5

Views: 3665

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477854

You can obtain the queryset of Humans that own (at least) one Jacket with:

Human.objects.filter(jacket__isnull=False).distinct()

This works because we make a LEFT OUTER JOIN on the Jacket model, and we filter out the ones without a related Jacket with jacket__isnull=False. By using .distinct() we prevent that the same Human is returned multiple times (once per related Jacket).

In the query it uses the related_name_query to reference the related object, which is by default the name of the model in lowercase. In case a related_name is specified, it will use the related_name.

Upvotes: 5

Related Questions