默认django对象用作基础

时间:2017-12-31 12:00:35

标签: django django-models one-to-one

我试图建立一个网站成员可以创建可以进行各种设置的游戏的网站(比如玩家的最大数量)。

团队将有一个设置对象,其中包含这些设置的默认值,但用户可以根据需要更改每个游戏的这些值(不影响团队的默认值)。

我想知道设置它的最佳方法是什么。因此,给出以下模型: -

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)更有意义吗?

1 个答案:

答案 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上的反向关系来强制执行这种简单性。