Reputation: 3236
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
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