Django circular model reference

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)

Here is another way to tackle this problem. Instead of creating a circular dependency, I created an additional table that stores the relationship between players and teams. So in the end it looks like this:

class Team(Model):
    name = CharField(max_length=50)

    def get_captain(self):
        return PlayerRole.objects.get(team=self).player

class Player(Model):
    first_name = CharField(max_length=50)
    last_name = CharField(max_length=50, blank=True)

    def get_team(self):
        return PlayerRole.objects.get(player=self).team

PLAYER_ROLES = (
    ("Regular", "Regular"),
    ("Captain", "Captain")
    )

class PlayerRole(Model):
    player = OneToOneField(Player, primary_key=True)
    team = ForeignKey(Team, null=True)
    role = CharField(max_length=20, choices=PLAYER_ROLES, default=PLAYER_ROLES[0][0])
    class Meta:
        unique_together = ("player", "team")

It might be slightly less efficient in terms of storage than the suggested workaround, but it avoids the circular dependency and keeps the DB structure clean and clear. Comments are welcome.


as you can see in the docs, for exactly this reason it is possible to specify the foreign model as a string.

team = models.ForeignKey('Team')

Tags:

Python

Django