我无法理解使用直通模型使用ManyToMany模型字段。没有ManyToMany字段,我可以很容易地实现相同的功能。考虑以下Django的文档:
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
我不明白,如何使用ManyToMany字段比简单地删除它并使用相关管理器更好。例如,这两个模型将更改为以下内容:
class Group(models.Model):
name = models.CharField(max_length=128)
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE, related_name='members')
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
我在这里缺少什么?
答案 0 :(得分:9)
是的,使用明确的through
表基本上不需要ManyToManyField
。
拥有它的唯一真正好处是,如果您发现相关经理方便。就是这样:
group.members.all() # Persons in the group
看起来比这更好:
Person.objects.filter(membership_set__group=group) # Persons in the group
在实践中,我认为两者兼顾的主要原因是人们常常以简单的ManyToManyField
开始;意识到他们需要一些额外的数据并添加一个through
表;然后由于使用两个管理器的代码而导致两者都结束。
答案 1 :(得分:0)
我对凯文·克里斯托弗·亨利 (Kevin Christopher Henry) 的回答有疑问。
我不认为没有 group.members.all()
的 through="members"
等价物是 Person.objects....
。
相反,如果 M2M 字段在 group.person_set.all()
侧,我认为它是 Person
。或者 group.persons.all()
如果 M2M 字段在 Group
内。
但我认为没有 through=..
你无法控制创建的表。它包含并将仅包含 2 个字段:相关行的两个 ID。
但是使用 through=..
,您可以自己创建模型并添加(现在或以后)附加字段,这通常是有充分理由的。此类字段的示例:valid_from = DateField()
左右。