matyas
matyas

Reputation: 2796

Django how to filter queryset based on nested many to many relations in one query

Let's say I have a product that can have various child products, and the models are defined like this

class Country(models.Model):
   name = models.CharField()

class Product(models.Model):
   parent = models.ForeignKey(
        'self', null=True, blank=True, related_name='children')
   name = models.CharField()
   countries = models.ManyToManyField(Country)

my goal is to retrieve all products that have one or more child products that are linked to a specific country.

In my use case I need this information as a Queryset. What I have tried is this and it works:

valid_products = []
desired_country = Country.objects.get(name='mycountry')
for product in Product.objects.all():
    for child in product.children.all():
        countries = child.countries.all()
        for country in countries:
            if country == desired_country:
                valid_products.append(product.id)
desired_queryset = Product.objects.filter(pk__in=valid_products)

This method requires and additional query to convert my result into a queryset and I would like to avoid that.

Is it possible to filter a queryset like this directly with the Django ORM?

Upvotes: 3

Views: 2237

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599610

You can simply follow the relations using the double-underscore syntax. So:

desired_queryset = Product.objects.filter(children__countries= desired_country)

Upvotes: 7

Related Questions