How to filter model results for multiple values for a many to many field in django


Question

I have the following Model:

class Group(models.Model):
    member = models.ManyToManyField(Player, through='GroupMember')
    name = models.CharField(max_length=20, unique=True)
    join_password = models.CharField(max_length=20)
    date_created = datetime.datetime.now()

    def __unicode__(self):
        return str(self.name)

class GroupMember(models.Model):
    member = models.ForeignKey(Player)
    group = models.ForeignKey(Group)
    rating = models.IntegerField(default=1500)
    played = models.IntegerField(default=0)
    wins = models.IntegerField(default=0)
    losses = models.IntegerField(default=0)
    experience = models.IntegerField(default=0)
    admin = models.BooleanField(default=0)

As you can see the group is made up of members who are players. What I would like to do is given two players I would like to be able to filter the groups that contain both of these players but I am unsure how to do this type of query.

1
27
2/23/2012 9:52:57 AM

Accepted Answer

If your Player model looks like this:

class Player(models.Model):
    name = models.CharField(max_length=200)

Then, you can execute this query:

Group.objects.filter(player__name__in=['Player1','Player2'])

Which roughly translates to "find all groups that have players whose names match 'Player1' and 'Player2'"

Or you can fetch the player objects individually:

p1 = Player.objects.get(name='Player1')
p2 = Player.objects.get(name='Player2')
groups = Group.objects.filter(player=p1).filter(player=p2)
36
4/15/2013 3:55:17 AM

The easiest solution for you will be:

p1 = Player.objects.get(id=1)
p2 = Player.objects.get(id=2)
groups = Group.objects.filter(member=p1).filter(member=p2)

Note that you can't use the __in filter like this because this will result in an OR and return groups that don't contain both players:

Group.objects.filter(member__in=[1, 2])

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon