我试图建立一个网站成员可以创建可以进行各种设置的游戏的网站(比如玩家的最大数量)。
团队将有一个设置对象,其中包含这些设置的默认值,但用户可以根据需要更改每个游戏的这些值(不影响团队的默认值)。
我想知道设置它的最佳方法是什么。因此,给出以下模型: -
class GameSettings(models.Model):
max_players = models.IntegerField(default=10)
etc.
我应该
a)向GameSettings添加一对一的关系给Team和Game模型,如下所示: -
class Team(models.Model):
gamesettings = models.OneToOneField(GameSettings)
class Game(models.Model):
gamesettings = models.OneToOneField(GameSettings)
或
b)为GameSettings模型添加2个一对一关系,如下所示: -
class GameSettings(models.Model):
group = models.OneToOneField(Group, null=True)
game = models.OneToOneField(Game, null=True)
max_players = models.IntegerField(default=10)
etc.
最明智的解决方案似乎是a)但如果我这样做,那么无论何时创建新游戏,我都需要以某种方式复制团队的游戏设置。但是如何?
或者b)更有意义吗?
答案 0 :(得分:0)
游戏设置看起来应该尽可能简单,然后使用方法创建副本很容易(并且模型很容易测试):
class GameSettings(models.Model):
max_players = models.IntegerField(default=10)
...
def override(self, **overrides):
vals = {f: overrides.get(f, getattr(self, f)) for f in self_meta.get_all_field_names()}
return self.__class__.objects.create(**vals)
然后创建一个新游戏:
class Team(models.Model):
default_team_settings = models.ForeignKey(GameSettings, related_name="+")
class Game(models.Model):
default_game_settings = models.ForeignKey(GameSettings, related_name="+")
myteam = Team.objects.get(..)
newgame = Game.objects.create(
default_game_settings=myteam.default_team_settings.override(max_players=2, ...),
...
)
这也应该更容易测试,因为模仿{/ 1}}来自游戏/团队的成员比来自GameSettings
的游戏/团队成员更容易(因为GameSettings
被审慎保留在这个版本中很简单)。我已经禁用了fkeys上的反向关系来强制执行这种简单性。