Search code examples
djangomany-to-manydjango-filterdjango-q

Django filter on multiple many-to-many rows


I'm pretty new to Django and I have a problem on filtering on many-to-many objects. I have a many-to-many relationship

class Person(models.Model):
  name = models.CharField(max_length=128)

  def __unicode__(self):
      return self.name 
class Group(models.Model):
  name = models.CharField(max_length=128)
  members = models.ManyToManyField(Person, through='Membership')

  def __unicode__(self):
      return self.name
class Membership(models.Model):
  person = models.ForeignKey(Person)
  group = models.ForeignKey(Group)
  date_joined = models.DateField()
  invite_reason = models.CharField(max_length=64)

I can filter on Persons that are related to One single group

persons=Person.objects.filter(Q(group__name='Group1'))

But what I want to achieve is to filter on Persons that are exactly in two groups.

Example:

  • Person1 is in Group1
  • Person2 is in Group1 and Group2.

The filter should only return Person2.

Any tips how to create a filter for this?


Solution

  • I think this should do it ...

    groups = ["Group1","Group2"]
    persons = Person.objects.annotate(count=Count('name')).filter(count__gte=len(groups)).filter(reduce(operator.or_, (Q(group__name=x) for x in groups)))