Question about how to perform a django query. I have a Game model with a 'through' ManyToManyField to the User model.
class Game(models.Model):
# other misc game-description fields...
players = models.ManyToManyField(User, through='PlayerGameResult',
blank=True, null=True)
class PlayerGameResult(models.Model):
game = models.ForeignKey(Game)
player = models.ForeignKey(User)
dtime_played = models.DateTimeField(default=datetime.now)
# ...
If a particular game has been played by 1+ players, then the players field in the Game model will have 1+ references. Otherwise players is null. For the query question please refer to the ?????? below....
# all games not yet played b开发者_开发问答y this user...
games_qset = Game.objects.exclude(players__username=request.user.username)
# out of all the games not played by this user, extract the ones not
# yet played by anyone else either (this user would be the 1st player)
games_unplayed_qset = games_qset.filter(players__isnull=True)
# here's the question: out of all the games that have not been played by
# this user, get a queryset that extracts only the games that have been
# played by more than 10 (GAME_WITH_FEW_PLAYERS_THRESHOLD) players
# ?????? this is the query I don't know how to make... ?????
#
# in the following example, I want to get back a queryset that includes only
# Game Ids 6 and 19, because they have players count 20 and 12 (> threshold 10)
#
# (Pdb) for rec in games_qset: print rec
# Game id 6, Num players: 20
# Game id 7, Num players: 5
# Game id 13, Num players: 0
# Game id 19, Num players: 12
#
# for a count of all games that have been played by at least one player:
# (Pdb) games_qset.filter(players__isnull=False).count()
# 3
#
Any ideas? Thank you. Juan
It's confusing when you say "extract" as in exclude.
The answer is in annotation and aggregation.
http://docs.djangoproject.com/en/dev/topics/db/aggregation/
from django.db.models import Count
Games.objects.annotate(num_players=Count('players')).filter(num_players__gt=10)
I think you are looking for annotate - based on example in docs
q = Game.objects.filter(players__isnull=False).annotate(Count('players'))
q[0].players__count #prints first games players
or to filter by count
q = Game.objects.annotate(num_players=Count('players')).filter(num_players__gt=1)
精彩评论