Модели Django: игрок может играть во множество игр, а в одну игру могут играть ровно два игрока?

У меня проблема в моих моделях django...

у меня есть 2 модели (таблицы) Player и Game как отношения многие ко многим, и третья модель как промежуточная таблица между ними, которая имеет имя пользователя игрока как внешний ключ (имя пользователя является таблицей игрока pk) и game_id fk также, и дополнительный атрибут score, проблема в том, что более чем 2 игрока могут иметь одну и ту же игру, и это не то, что я хочу, что я хочу, чтобы каждая игра могла быть сыграна точно и только двумя игроками.

как этого добиться с помощью django?

Здесь представлены модели:


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)

обращайтесь ко мне за любой дополнительной информацией.

я попытался добавить unique_together в класс Meta, но это не решило проблему

Модифицируйте модель Player_game, чтобы она имела уникальное ограничение на поле game, гарантирующее, что в каждой игре может быть только два игрока, связанных с ней. Реализуйте пользовательский метод проверки или переопределите метод сохранения, чтобы обеспечить соблюдение ограничения программно.

введите описание изображения здесь

Нужны ли вам сложности, связанные с соединением ManyToMany игры и игрока с ограничением, что в одну игру могут играть только два игрока?

Возможно, вам будет проще иметь два обычных ForeignKey, скажем player1 и player2 (или black и white, где есть такая асимметрия). Если эти ключи можно обнулить, то один игрок null может описывать игрока, желающего сыграть, но ожидающего соперника. Для игры, находящейся в процессе или завершенной, требуются все три ключа.

Недостатком является то, что такая конструкция ломается, если впоследствии вы захотите ввести многопользовательские игры с разным количеством участников.

Эй, ребята, спасибо за ваше время, ваши ответы так хороши, я понял, что моя текущая реализация будет работать успешно, потому что когда новая игра начинается, она будет храниться как новая игра recoed (новый game_id), так что не будет никаких проблем. Спасибо вам еще раз, ребята <3

Вернуться на верх