class Person(models.Model):
age = models.IntegerField()
class Group(models.Model):
people = models.ManyToManyField(Person,through=Membership)
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
existing = models.BooleanField()
This is the simplified class structure and what I want to query is:
A queryset on group such that there are some people with membership such that existing
is true.
I have tried using Group.objects.filter(membership__existing=True)
but it seems to be grabbing all the Groups.
What is the most efficient way to filter out the queryset?
I created a sample app using your model definitions, and the filter you've specified works fine. I had to change the through
attribute of the people
field to be a string, as Membership
isn't defined yet. I also added a name field to Group
to make it easier to test.
class Person(models.Model):
age = models.IntegerField()
class Group(models.Model):
name = models.CharField(max_length=255)
people = models.ManyToManyField(Person, through='Membership')
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
existing = models.BooleanField()
Then in the console:
>>> p1 = Person.objects.create(age=10)
>>> p2 = Person.objects.create(age=20)
>>> has_existing = Group.objects.create(name='has_existing')
>>> has_non_existing = Group.objects.create(name='has_non_existing')
>>> has_none = Group.objects.create(name='has_none')
>>> Membership.objects.create(person=p1, group=has_existing, existing=True)
>>> Membership.objects.create(person=p2, group=has_non_existing, existing=False)
>>> existing = Group.objects.filter(membership__existing=True)
>>> assert(len(existing) == 1)
>>> assert(existing[0].name == 'has_existing')