为什么在Django模型中使用ManyToManyField的“through”参数?

时间:2012-01-11 17:09:29

标签: django django-models many-to-many django-orm

浏览Django文档并试图弄清楚使用“通过”参数。这是指向doc的链接。

示例:

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

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

为什么Group的“members”属性需要?成员资格的“组”外键是否足以遵循关系并访问该信息?

4 个答案:

答案 0 :(得分:10)

我认为你对这个问题的看法有点太过分了。假设你没有使用through

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

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person)

    def __unicode__(self):
        return self.name

Django,在幕后,基本上为您创建了以下模型:

class GroupPerson(models.Model)
    group = models.ForeignKey(Group)
    person = models.ForeignKey(Person)

创建Membership模型的原因是添加默认模型Django 自动创建的额外数据,默认情况下不会,但由于您不再使用默认模式,你必须使用through告诉Django。基本上,你保留了Django为ManyToManyFields提供的API。

答案 1 :(得分:3)

为什么要这样做是因为Group有这个关系的字段,而不是必须通过其membership_set追溯关系。

如果不出意外,这可以使编写查询更简单。至少,这可以使程序员的生活更轻松,代码更容易阅读。一个充分优化的ORM将能够生成适当的索引以加速这种访问(除非我非常错误,django确实这样做;或者至少南方确实这样做。)

答案 2 :(得分:2)

这样,从Group中,您可以直接访问成员。您不一定要直接处理Membership对象(用户我甚至都看不到它们)。您只需要存储一些额外信息的组。将成员资格视为人与群之间关联的元数据。

答案 3 :(得分:1)

through table用于存储 relation 的属性,在这种情况下,例如, Person加入特定Group

的日期