Home > Blockchain >  Django OneToOneField Structure
Django OneToOneField Structure

Time:02-22

I have been researching and looking through all the docs but I am still a bit confused, I think maybe because there are multiple ways to use the OnToOneField.

I have 4 models, Pregame, Ingame, Postgame and Game. And I want 'Game' to contain the other three models.

As of right now it looks like this...

    class Pregame(models.Model):
        game_id = models.CharField(max_length=10)
        other fields...

        def __str__(self):
            return str(self.game_id)

    class Ingame(models.Model):
        game_id = models.CharField(max_length=10)
        other fields...

        def __str__(self):
            return str(self.game_id)

    class Postgame(models.Model):
        game_id = models.CharField(max_length=10)
        other fields...

        def __str__(self):
            return str(self.game_id)

    class Game(models.Model):
        game_id = models.CharField(max_length=10)
        pregame = models.OneToOneField(
            Pregame, on_delete=models.CASCADE, null=True)
        ingame = models.OneToOneField(
            Ingame, on_delete=models.CASCADE, null=True)
        postgame = models.OneToOneField(
            Postgame, on_delete=models.CASCADE, null=True)

        def __str__(self):
            return str(self.game_id)

I am using OnToOne because each Game will only have one Pregame, Ingame and Postgame and the other three models will only belong to one Game.

I have a couple questions I am confused about.

Will I be able to have a Game object if one of the other model objects doesn't exist yet? Like if there is a Pregame but no Ingame or Postgame, will Game still exist with just Pregame inside of it? I seen a couple videos where they did a default='{}', is that what I should be doing?

Each model has game_id and that is how I am connecting them all together into the'Game' object. Is there a OneToOneField option like game_id=game_id so the 'Game' model will automatically link all the models together or would I still have to do that separate?

Thank you for your help and knowledge.

CodePudding user response:

First of all, you don't have to set game_id on the *game entities. You can just add related_name:

class Game(models.Model):
    game_id = models.CharField(max_length=10)
    pregame = models.OneToOneField(
        Pregame, on_delete=models.CASCADE, null=True, related_name="game")
    ingame = models.OneToOneField(
        Ingame, on_delete=models.CASCADE, null=True, related_name="game")
    postgame = models.OneToOneField(
        Postgame, on_delete=models.CASCADE, null=True, related_name="game")

class Pregame(models.Model):
    other fields...

    def __str__(self):
        return str(self.game_id)

Will I be able to have a Game object if one of the other model objects doesn't exist yet? Like if there is a Pregame but no Ingame or Postgame, will Game still exist with just Pregame inside of it? I seen a couple videos where they did a default='{}', is that what I should be doing?

Yes, a Game object can exist even without a *game, as you added null=True. You should use a default when your model does not accept null/empty values.

Each model has game_id and that is how I am connecting them all together into the'Game' object. Is there a OneToOneField option like game_id=game_id so the 'Game' model will automatically link all the models together or would I still have to do that separate?

Once you create such a model, you have access via the Game entity. For example from going to pregame to postgame:

postgame = pregame.game.postgame
  • Related