Django中的多对多关系

时间:2011-05-10 21:52:21

标签: django database-design django-models

我正在为Django的一些模型设计并希望得到一些建议。我有一个团队模型,其中许多用户可以参与其中。用户也可以是许多团队的成员,但他们不能两次成为同一团队的成员。我还想为每个团队/用户组合跟踪单独的信息。最重要的是,每个团队都会有一个“管理员”用户,但每个团队可能只有一个管理员。我有一些浓缩的数据模型定义如下:

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

class Membership(models.Model):
    user = models.ForeignKey(User)
    team = models.ForeignKey(Team)
    extra_data = models.CharField()

所以我想我的两个问题是:

1)我如何制作它以便在会员模型上,不会出现多次用户和团队组合?

2)是否有更好的方法来表示团队中的管理员,同时确保每个团队只有一个?看起来如果我像这样存储管理员,同时强制执行只有一个管理员的规则,查询所有团队成员变得太麻烦,因为管理员不会在Membership表中。如果它们存储在成员资格中,那么我必须执行另一个查询以查看他们是否是该团队的管理员。在会员中使用“is_admin”字段的想法突然出现在脑海中,但我不确定如何保持每个团队1个管理员的约束。

任何帮助都会非常感激。

更新: 看起来像unique_together元标记是我在第一个问题上寻找的。我仍然对第二个感到好奇....

2 个答案:

答案 0 :(得分:1)

第一个问题:

您可以添加约束来阻止它:

class Membership(models.Model):
    user = models.ForeignKey(User)
    team = models.ForeignKey(Team)
    extra_data = models.CharField()
    class Meta:
        unique_together = (('user','team'),)

第二个问题:

您可以向会员模型添加排名字段,并将'user'和'rank'设为unique_together,正整数字段。 rank == 1的用户是管理员。或类似的。它将强制执行您的方案,但编码维护它可能很麻烦。你可能会对自己所拥有的东西感觉更好。

答案 1 :(得分:0)

回答你的第二个问题:

为什么不将管理员包含在团队成员m2m中?

如果您想要整个团队成员,包括管理员:

some_team.members

将管理员fk保留在团队模型上是有道理的,当您需要管理员时可以使用:

some_team.admin 

当你想要没有管理员的团队时,你可以使用:

some_team.members.exclude(pk = some_team.admin.pk)