【问题标题】:Many to Many relationships in DjangoDjango中的多对多关系
【发布时间】:2011-08-22 20:26:47
【问题描述】:

我正在为 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 元标记是我在第一个问题上要寻找的。不过我还是对第二个很好奇....

【问题讨论】:

  • 我认为在 Team 模型中建立管理员关系是正确的。就关系的性质而言,这是最合适的地方。 QuerySet API 可以让您获得几乎任何您想要的东西,通常只需要最少的查询。

标签: django database-design django-models


【解决方案1】:

第一个问题:

你可以添加一个约束来防止它:

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

第二个问题:

您可以在会员模型中添加一个排名字段,并将“用户”和“排名”设为唯一的正整数字段。 rank == 1 的用户是管理员。或类似的。它将强制执行您的方案,但编写维护它的代码可能很麻烦。你可能会更好地利用你所拥有的。

【讨论】:

  • 感谢您的帮助。当我看到你已经回答时,我刚刚完成了关于 unique_together 的帖子的编辑。
【解决方案2】:

回答你的第二个问题:

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

当您想要包括管理员在内的整个团队时:

some_team.members

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

some_team.admin 

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

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

【讨论】:

  • 我对这种方法唯一关心的是如何强制在创建团队并添加管理员时,他们也作为成员添加到团队中。在团队注册页面中,这很容易强制执行,但我有点担心通过其他界面(如管理员)创建的团队必须依赖用户手动添加。
  • 也许这是覆盖团队的保存方法并自动将管理员添加为第一个团队成员的好地方?
猜你喜欢
  • 2021-09-11
  • 2011-06-02
  • 2012-02-26
  • 1970-01-01
  • 2012-10-20
相关资源
最近更新 更多