I\'m starting to work on a small soccer league management website (mostly for learning purposes) and can\'t wrap my mind around a Django models relationship. For simplicity,
Now can be used the AppConfig feature to import models:
Retailer = apps.get_model('retailers', 'Retailer')
retailer = Retailer.objects.get(id=id)
Neither of the answers here are really that great - creating circular references is never a good idea. Imagine if your database crashed and you had to create it from scratch - how would you create player before team is created, and vice versa? Look a question here: ForeignKey field with primary relationship one I asked a few days ago. Put a Boolean on Player that specifies the captain, and put some pre-save hooks that validate every team must have one-and-only-one captain.
Although there is nothing wrong with having two references to the same model, perhaps there is a better way to solve this particular problem.
Add a boolean to the Team
model to identify a player + team combination as captain:
class Team(models.Model):
player = models.ForeignKey(Player)
name = models.CharField(max_length=50)
is_captain = models.BooleanField(default=False)
To search for a team's captain:
Team.objects.filter(is_captain=True)
Personally I don't like this method because the search semantics don't make sense (ie, a "team" is not a "captain").
The other approach is to identify each player's position:
class Player(models.Model):
name = models.CharField(max_length=50)
position = models.IntegerField(choices=((1,'Captain'),(2,'Goal Keeper'))
jersey = models.IntegerField()
def is_captain(self):
return self.position == 1
class Team(models.Model):
name = models.CharField(max_length=50)
player = models.ForeignKey(Player)
def get_captain(self):
return self.player if self.player.position == 1 else None
This makes a bit more sense when you search:
Player.objects.filter(position=1)
(return all captains)
Team.objects.get(pk=1).get_captain()
(return the captain for this team)
In either case, however you have to do some pre save checks to make sure there is only one player for a particular position.
You could use the full application label in the foreign key to the model not yet defined, and use related_name to avoid name conflict:
class Team(models.Model):
captain = models.ForeignKey('myapp.Player', related_name="team_captain")
class Player(models.Model):
team = models.ForeignKey(Team)
This is what you were looking for:
class Team(models.Model):
name = models.CharField()
captain = models.ForeignKey('Player')
class Player(models.Model):
name = models.CharField()
team = models.ForeignKey(Team)
Have a Captain table that has player/team columns along with your other tables, and make captain a method of Team:
class Team(models.Model):
name = models.CharField()
def captain(self):
[search Captain table]
return thePlayer
class Player(models.Model):
name = models.CharField()
team = models.ForeignKey(Team)
class Captain(models.Model):
player = models.ForeignKey(Player)
team = models.ForeignKey(Team)
You'd have to check that you never have more than one captain in the same team though... But you don't have any circular references that way. You could also end up with a captain who isn't in the team he's flagged as captain of. So there's a few gotchas this way.