Reputation: 753
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.
Upvotes: 49
Views: 100037
Reputation: 3840
For me __in
did not work. I ended up using the complex Q lookup
which works perfectly and you can or
filter conditions with. Use it like this:
from django.db.models import Q
p1 = Player.objects.get(name='Player1')
p2 = Player.objects.get(name='Player2')
querySet = Group.objects.filter(Q(member=p1) | Q(member=p2))
Upvotes: 13
Reputation: 174662
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)
Upvotes: 66
Reputation: 3132
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])
Upvotes: 32