mic
mic

Reputation: 1266

Django filter objects based on property in ForeignKey set

I have models that look something like this:

class Type(models.Model):
    name = models.CharField(max_length=50)
    notes = models.CharField(max_length=50)

class Instance(models.Model):
    type = models.ForeignKey(Type, on_delete=models.CASCADE)
    color = models.CharField(max_length=50)
    quantity = models.PositiveIntegerField()

I want to get a list of all Types that have at least one Instance whose quantity is greater than 0. How can I express that?

In (pseudo) vanilla Python, this would be something like:

[type for type in Type.objects.all()
       if type.instance_set.objects.filter(lambda instance: instance.quantity > 0)]

I tried

available_types = Type.objects.filter(Q(instance_set__contains=Q(quantity__gt=0))

but this doesn't work because Django is looking for quantity as an attribute of Type, and of course doesn't find it, because it's an attribute of Instance.

Upvotes: 3

Views: 1467

Answers (2)

Cuyler Quint
Cuyler Quint

Reputation: 196

why not just query the Instance objects for instance.quantity > 0 and then use values_list distinct notation?

Something along the lines of:

types_with_quantity_gt_zero = Instance.objects.filter(quantity__gt=0).values_list('type', flat=True).distinct()

Upvotes: 2

Daniel Roseman
Daniel Roseman

Reputation: 599610

You can filter directly across a relationship:

Type.objects.filter(instance__quantity__gt=0)

Upvotes: 5

Related Questions