5

Suppose I have a list of id's: c = ['1', '2' , '3']

class Topic(Model):

 categories=ManyToManyField(Category)

How can I filter topics that have exact and only categories with id's from c?

Paul R
  • 2,631
  • 3
  • 38
  • 72

1 Answers1

11

You need to call .filter(categories=category_id) for each element in the c list.

c = [1, 2, 3]
topics = reduce(lambda qs, pk: qs.filter(categories=pk), c, Topic.objects.all())

And then if you want to exclude topics with additional categories (e.g. a topic with [1,2,3,4]), then you need to .annotate and .filter on the total count.

c = [1, 2, 3]
initial_qs = Topic.objects.annotate(cnt=models.Count('categories')).filter(cnt=len(c))
topics = reduce(lambda qs, pk: qs.filter(categories=pk), c, initial_qs)
Todor
  • 15,307
  • 5
  • 55
  • 62