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
字段?根据{{1}}的位置
由于
编辑(我应该更清楚):
我对中介表感兴趣,因为我会在关系中存储其他数据。
当我说使用时,我不是指定义模型,我的意思是使用这种关系(否则我会让Django做它的事情)。
如果我希望所有秒与第一个相关,它是否与获得与第二个相关的所有第一个完全相同,或者ManytoManyField
通过引入任何额外功能使{1}}比另一个更容易做出一个方向?
答案 0 :(得分:13)
从操作角度来看应该没有区别,因此唯一的区别在于模型的定义和影响它的事物(例如,Manager类)。
您也不总是需要定义“通过”类。 Django会自动为您执行此操作,而该类实际上所做的就是维护第三个表来跟踪其他两个表中每个相关记录的相应ID。您必须决定是否要向第三个表添加任何重要的内容。
例如,假设您正在为会议设计Web应用程序。他们可能希望存储有关与会者(个人和公司)以及发言人和赞助商(也包括个人和公司)的信息。公司的部分模型可能如下所示:
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)
但这很快就会变得很麻烦,而且你会有很多与赞助无关的参与公司。此外,您可能希望在网站上跟踪他们的排名/包裹(毕竟,更大的赞助商获得更大的位置):
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”属性。这意味着我们可以使用该名称通过ConferenceSegment
实例访问Company
对象:
c = Company.objects.get(...)
segments = c.sponsored_segments.all()
希望这有帮助。
答案 1 :(得分:1)
向模型添加多对多字段时,会在数据库中创建一个单独的表,用于存储两个模型之间的链接。如果您不需要在第三个表格中存储任何额外信息,那么您就不必为其定义模型。
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
我无法想到在第一或第二模型中定义多对多字段之间的任何区别:
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')