Проектирование моделей Django: Соло-игрок ИЛИ команда с игроками в игре
Я разрабатываю веб-интерфейс на основе Django для игры, в которую можно играть как в одиночку, так и в команде. Игра основана на очках; побеждает та сторона, которая первой наберет заданное количество очков. Для последующей статистики и отображения, очки имеют временную метку.
Моя проблема: Как я могу иметь либо два Player
ИЛИ два Team
в одном Game
? На данный момент мои модели выглядят следующим образом:
from django.db import models
# Create your models here.
class Player(models.Model):
slug = models.SlugField(unique=True) # will be autogenerated when inserting new Instance
name = models.CharField(max_length=100)
wins = models.IntegerField()
losses = models.IntegerField()
picture = models.ImageField(upload_to='images/player_pics')
# games_played = wins + losses
def __str__(self):
return self.name
class Team(models.Model):
slug = models.SlugField(unique=True)
name = models.CharField(max_length=100)
players = models.ManyToManyField(Player)
wins = models.IntegerField() # from here on seems redundant to Player class
losses = models.IntegerField()
picture = models.ImageField(upload_to='images/team_pics')
# games_played = wins + losses
def __str__(self):
return self.name
class Point(models.Model):
val = models.IntegerField()
timestamp = models.DateTimeField()
class Game(models.Model):
slug = models.SlugField(unique=True)
timestamp = models.DateTimeField()
players = models.ManyToManyField(Player) # here should be either Team or Player
points = models.ManyToManyField(Point)
Моя идея заключалась в том, чтобы реализовать другой класс типа GameParty
, который может быть либо Player
, либо Team
, но там та же проблема. Мне также не нравятся избыточные поля, такие как победы и поражения.
Надеемся на ваш отзыв!
Вам не нужно жестко кодировать выигрыши, проигрыши и сыгранные партии, потому что вы можете получить эти значения с помощью запроса, используя внешние ключи и отношения "многие-ко-многим" (вы также можете создать динамическое свойство в вашей модели для возврата запроса, чтобы избежать повторений). Измените свои модели:
from django.db import models
class Player(models.Model):
slug = models.SlugField(unique=True)
name = models.CharField(max_length=100)
picture = models.ImageField(upload_to='images/player_pics')
def __str__(self):
return self.name
class Team(models.Model):
slug = models.SlugField(unique=True)
name = models.CharField(max_length=100)
players = models.ManyToManyField(Player)
picture = models.ImageField(upload_to='images/team_pics')
def __str__(self):
return self.name
class Point(models.Model):
player = models.ForeignKey(Player, on_delete=models.PROTECT, related_name='points') # You need to associate the player with the point
val = models.IntegerField()
timestamp = models.DateTimeField()
class Game(models.Model):
slug = models.SlugField(unique=True)
timestamp = models.DateTimeField()
players = models.ManyToManyField(Player, related_name='games')
points = models.ManyToManyField(Point)
Теперь, например, для получения игр, сыгранных игроком, можно написать такой запрос:
player = Player.objects.get(id=1)
games_played = player.games.count()
Или с динамическим свойством (это свойство не вставляется в базу данных, но оценивается при каждом вызове, поэтому вам не нужно его обновлять):
class Player(models.Model):
# Your fields and methods
@property
def games_played(self):
return self.games.count()
Для написания запросов возьмите ссылки из документации. Если вы хотите связать также команды с играми, вы можете создать дополнительную таблицу или использовать генеральное отношение.