如何使用Django创建三联接表
时间:2020-03-05 18:56:07 来源:igfitidea点击:
使用Django的内置模型,如何在三个模型之间创建三重联接。
例如:
- 用户,角色和事件是模型。
- 用户有许多角色,而角色有许多用户。 (多对多)
- 事件有许多用户,而用户有许多事件。 (多对多)
- 但是对于任何给定事件,任何用户都只能拥有一个角色。
该如何在模型中表示?
解决方案
回答
我建议为此创建一个完全独立的模型。
class Assignment(Model): user = ForeignKey(User) role = ForeignKey(Role) event = ForeignKey(Event)
这使我们可以执行所有常用的模型工作,例如
user.assignment_set.filter(role__name="Chaperon") role.assignment_set.filter(event__name="Silly Walkathon")
剩下的唯一一件事就是强制执行每个用户每事件一个角色的限制。我们可以通过覆盖保存方法(http://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods)或者使用信号(http: //docs.djangoproject.com/en/dev/topics/signals/)
回答
我将角色建模为用户和角色之间的关联类,因此,
class User(models.Model): ... class Event(models.Model): ... class Role(models.Model): user = models.ForeignKey(User) event = models.ForeignKey(Event)
并在管理器或者SQL约束中为每个事件的每个用户强制一个角色。
回答
zacherates写道:
I'd model Role as an association class between Users and Roles (...)
我也建议使用此解决方案,但是我们也可以使用Django提供的一些语法糖:ManyToMany与其他字段的关系。
例子:
class User(models.Model): name = models.CharField(max_length=128) class Event(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(User, through='Role') def __unicode__(self): return self.name class Role(models.Model): person = models.ForeignKey(User) group = models.ForeignKey(Event) date_joined = models.DateField() invite_reason = models.CharField(max_length=64)