Mikael
Mikael

Reputation: 3236

Django - querying objects via many-to-many relation

My models look like this:

class Category(models.Model):
    name = models.CharField(_('name'), max_length=50)

class Product(models.Model):
    name = models.CharField(_('product name'), max_length=40)
    category = models.ManyToManyField(Category)

I am trying to build a filter query where I can select 1 or many categories and return products that is connected to all the selected categories.

Example

Product_1 - Belongs to category_1, category_2

Product_2 - Belongs to category_1, category_2 and category_3

When filtering on category_1 and category_2 both products should be returned by the query. When filtering on all 3 categories only Product_2 should be returned since this is the only product related to all selected categories.

The filtering will be dynamic so the number of categories to filter on could be infinite.

How do I do this? I have tried doing

Product.objects.filter(category__in=[1,2,3])

But that gives me both product_1 and product_2 since they match ANY of the categories.

I have tried creating a Q filter

Product.objects.filter(Q(category__id=1), Q(category__id=2))

But this doesn't return any product.

How would a query like this be constructed to work?

Upvotes: 0

Views: 1903

Answers (1)

schneck
schneck

Reputation: 10827

I don't know an easy solution for this, but maybe you can use this workaround:

Product.objects.filter(category__in=[1,2,3]).annotate(total=Count('category')).filter(total=3)

Alternatively, you could chain filters:

Product.objects.filter(category=1).filter(category=2).filter(category=3)

Upvotes: 4

Related Questions