基于django中另一个字段的唯一值字段

时间:2009-07-23 16:33:38

标签: database django django-models django-admin unique

前言:我是django和db design的新手。

SUPEREDIT:我做了一些重大修改,所以在我的修改之前的答案可能会引用不在这里的事情。我道歉。

我会正确使用代码: models.py:

class Player(models.Model):
    name = models.CharField()

class Team(models.Model):
    name = models.CharField()
    members = models.ManyToManyField(Player, through='Membership')

class Word(models.Model):
    word = models.CharField(unique=True)
    definition = models.CharField()
    ...

class Ownership(models.Model):
    owner = models.ForeignKey(Player)
    team = models.ForeignKey(Team)
    word = models.ForeignKey(Word)

class Membership(models.Model):
    team = models.ForeignKey(Team)
    player = models.ForeignKey(Player)

已填充Word表格。 在管理员中我创建了一个播放器。然后我创建一个团队并向其添加成员。我已将所有权添加到管理员。我创建了一个新的所有权,我可以从球员,球队和单词中挑选。我想设置一个约束,如果一个玩家拥有一个给定团队的单词,那么属于该团队的玩家就不能拥有该团队中的单词。他们可能在其他团队中拥有这个词。

现在的样子。我可以在同一个团队中有两个不同的玩家拥有相同的单词。坏。基本上我希望管理员说出这个团队中拥有的所有单词,而不是在下拉列表中提供它们。

我如何建模这种关系?如何在管理员中获得此功能?

编辑:我添加了会员模型只是为了表明我正试图解决另一个问题。正如我所说,这是我真正合作的简单例子。如你所见,我已经完成了会员关系,我正试图解决一个单独的所有权问题。

1 个答案:

答案 0 :(得分:3)

您的架构不正确。您应该使用“多对多关系中的额外字段”as seen here in the Django docs

It is also highlighted here on SO.

Look into unique_together代表你的“团队号码”协会。我不确定它是否也可以与多对多方法中的额外字段一起使用。否则,您可以在视图中强制执行唯一性,但我相信unique_together应该适用于您的情况。

对于1-99限制,您应该在表单验证中包含它,并且结合唯一性检查,您不需要整个表来存储数字1-99。

您的编辑更新

我不确定您是否真的阅读了我的帖子或关注了我的任何链接,但它解决了您所描述的问题,除非您当然还没有正确解释问题。一个数字的“所有权”不是你应该建模的东西,你应该在它所属的地方表达它:

class Player(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Team(models.Model):
    name = models.CharField(max_length=128)
    players = models.ManyToManyField(Player, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    player = models.ForeignKey(Player)
    team = models.ForeignKey(Team)
    number = models.IntegerField()
    """ ... """

    class Meta:
        unique_together = ('team', 'number')

所以请再次向我解释你如何需要一个玩家 - 团队 - 号码关联的所有权模型,因为我不确定你想要实现的是什么,这与我已经提供给你的东西是分开的。