Django 1.8 - 中介多对多直通关系 - 使用 'ManytoManyField' 的结果是什么?

Django 1.8 - Intermediary Many-to-Many-Through Relationship - What is the consequence of where 'ManytoManyField' is used?

Django 中通过关系实现多对多示例:

class First(models.Model):
    seconds = models.ManyToManyField(Second, through='Middle')

class Middle(models.Model):
    first = models.ForeignKey(First)
    second = models.ForeignKey(Second)

class Second(models.Model):

documentation on intermediary models 之后,要关联的对中只有一个模型包含 ManytoManyField,上面示例中的模型 First。这是正确的吗?

如果是,哪个模型应包含 ManytoManyField 字段?根据 ManytoManyField 的位置,从两端使用关系是否有任何差异?

谢谢

编辑(我应该更清楚):

我对中介感兴趣 table 因为我将有额外的数据来存储关系。

当我说用法时,我不是指定义模型,而是指使用关系(否则我会让 Django 来做这件事)。

如果我希望所有秒都与第一个相关,这是否与让所有第一个与第二个相关完全相同,或者 ManytoManyField 是否可以通过引入任何方法使一个方向比另一个方向更容易做到额外的功能?

当您向模型添加多对多字段时,会在数据库中创建一个单独的 table,用于存储两个模型之间的链接。如果您不需要在这第三个 table 中存储任何额外信息,那么您不必为其定义模型。

class First(models.Model):
    seconds = models.ManyToManyField(Second, related_name='firsts')

class Second(models.Model):
    pass

我想不出在第一个或第二个模型中定义多对多字段有什么区别:

class First(models.Model):
    pass

class Second(models.Model):
    firsts = models.ManyToManyField(First, related_name='seconds')

在这两种情况下用法是一样的:

firsts = my_second.firsts
seconds = my_first.seconds

从操作的角度来看应该没有区别,所以唯一的区别在于模型的定义和影响它的事物(例如,Manager classes)。

您也不必总是定义 "through" class。 Django 会自动为您完成这项工作,class 真正做的就是维护第三个 table 来跟踪其他两个 table 中每个相关记录的各自 ID。您必须决定是否要向第三个 table 添加任何重要内容。

例如,假设您正在为会议设计网络应用程序。他们可能想要存储有关与会者(个人和公司)以及演讲者和赞助商(也包括个人和公司)的信息。您的部分公司模型可能如下所示:

class Company(models.Model):
    name = models.CharField(max_length=100)
    sponsored_segment = models.ForeignKey(ConferenceSegment, null=True)

class ConferenceSegment(models.Model):
    title = models.CharField(max_length=100)

但这很快就会变得很麻烦,而且您将有很多与赞助无关的公司参加。此外,您可能希望在网站上跟踪他们的 rank/package(毕竟,赞助商越大,排名越高):

class Company(models.Model):
    name = models.CharField(max_length=100)

class ConferenceSegment(models.Model):
    title = models.CharField(max_length=100)
    sponsors = models.ManyToManyField(Company, through=u'Sponsor', related_name=u'sponsored_segments')

class Sponsor(models.Model):
    company = models.ForeignKey(Company)
    segment = models.ForeignKey(ConferenceSegment)
    rank = models.PositiveIntegerField()

另请注意 ManyToManyField 中的 "related_name" 属性。这意味着我们可以使用该名称通过 Company 实例访问 ConferenceSegment object:

c = Company.objects.get(...)
segments = c.sponsored_segments.all()

希望对您有所帮助。