Reputation: 1182
I am trying to write a django app for our weekly football match between friends.
I plan to have a model called Player and one called Game and for Game to have (and belong to) many Players so people can register themselves for the Game.
But at some point during the week, I want to assign some players to one team and some to another - but not until everyone has had a chance to register.
I can see that I could do this by making a Game have two Teams and for each Team to have many Players but this means that I'm using each Player that goes into a Team more than once in the Game model. This doesn't quite feel right to me.
I obviously also want to limit the choices for Players that can go into each Team to the Players who've registered for the Game.
Is there another way of modelling this so that I don't use the same data twice in the same Game object?
Upvotes: 0
Views: 199
Reputation: 7450
Since you need to keep track of registrations and assign players into teams
I don't see any other way. Actually scratch that.
The existence of an intermediate(GamePlayerMembership) instance can signify whether the player has registered or not for the game. So my take is this:
from django.db import models
class Player(models.Model):
name = models.CharField()
class Game(models.Model):
starts_when = models.DatetimeField()
players = models.ManyToManyField(Player, through='GamePlayerMembership', related_name='games_played')
def register(self, player):
return GamePlayerMembership.objects.create(game=self, player=player)
def assign(self, player, team):
try:
memb = GamePlayerMembership.objects.get(game=self, player=player)
memb.team = team
memb.save()
except GamePlayerMembership.DoesNotExist:
raise Exception('Player has not registered for the game')
class GamePlayerMembership(models.Model):
TEAMS = (
('home', 'Home'),
('guest', 'Guest')
)
game = models.ForeignKey(Game)
player = models.ForeignKey(Player)
team = models.CharField(max_length=5, choices=TEAMS, null=True, blank=True)
class Meta:
unique_together = ('game', 'player')
Upvotes: 1