Django models: a player can play many games and a game can be played exactly by two players?

I have a problem in my django models..

i have 2 models (tables) Player and Game as many to many relationship, and a third model as a intermediate table between them, that has player username as a foreignkey (the username is the player's table pk) and a game_id fk as well, and an additional attribute score, the problem is more than 2 players can have the same game, and this is not what i want, what i want is every single game can be played exactly and only by two players.

how can achieve that using django?

here is the models:

class Player(models.Model):
    username = models.CharField(max_length=20, primary_key=True)
    fname = models.CharField(max_length=20, blank=False)
    lname = models.CharField(max_length=20, blank=False)
    avatar = models.ImageField(upload_to='./app/avatars/', blank=True, null=True)
    is_online = models.BooleanField(default=False)
    game_theme = models.ImageField(upload_to='./app/themes/', blank=True, null=True)
    played_games_num = models.IntegerField(default=0)

    def __str__(self):
        return self.username

class Game(models.Model):

    mode_choices = {
        'classic': 'Classic',
        'vs_robot': 'Vs Robot'
    difficulty_choices = {
        -1: 'Vs Player',
        1: 'Easy',
        2: 'Medium',
        3: 'Hard'

    game_id = models.AutoField(primary_key=True)
    mode = models.CharField(max_length=10, choices=mode_choices)
    difficulty = models.IntegerField(choices=difficulty_choices)
    game_date_time = models.DateTimeField(auto_now_add=True)
    duration = models.IntegerField()
    players = models.ManyToManyField(Player, through='Player_game')

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

class Player_game(models.Model):
    username = models.ForeignKey(Player, on_delete=models.CASCADE)
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    score = models.IntegerField()

    class Meta:
        unique_together = ['username', 'game']

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

ask me for any additional information.

i tried to add unique_together in the class Meta but that didn't solve the problem

Modify the Player_game model to have a unique constraint on the game field, ensuring that each game can only have two players associated with it. Implement a custom validation method or override the save method to enforce the constraint programmatically.

enter image description here

Do you need the complications of a ManyToMany game to player connection with a constraint that only two players may play any one game?

You might find it easier to have two ordinary ForeignKeys, say player1 and player2 (or black and white where there is such an asymmetry). If these keys are nullable, one player null can describe a player wanting a game but waiting for an opponent. A game in progress or finished requires all three keys.

The downside is that this design breaks if you later want to introduce multi-player games with varying numbers of participants.

Hey guys thank you for ur time, ur answers are so good, i realised that my current implementing will work succesfuly, because when a new game start it will be stored as a new game recoed (new game_id) so there will be no problem. thank you again guys <3

Back to Top