Joh*_*han 8 django django-models
我无法理解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)
Run Code Online (Sandbox Code Playgroud)
我不明白的是,如何使用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)
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
Ale*_*kov 27
因此,我只是想向正在关注此问题并可能需要另一个示例来节省他们研究的人提供补充。一方面,我认为重要的是要注意,在OP的问题中,他应该删除模型Group
而不是People
模型,并从模型中删除匹配字段Membership
。这样,模型就回到了它最初的含义。
当考虑多对多关系时,该through
字段几乎可以被设计为多对多关系的“原因”。如果我们给命名法起一个不同的名称,可能会改变读者看到的内容:
class Person(models.Model):
name = models.CharField(max_length=128)
class Club(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='RegistrationReceipt')
class RegistrationReceipt(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
club = models.ForeignKey(Club, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
paid_dues = models.BooleanField(default = True)
fee_payment_date = models.DateTimeField()
Run Code Online (Sandbox Code Playgroud)
现在,您可以想象每当有成员加入该俱乐部时您自己都会添加各种逻辑。他们什么时候加入的?他们为什么加入?他们付钱了吗?他们的付款日期是什么时候?显然,您可以用不同的方式处理这种关系,但是您可以更清楚地看到“通过”在多对多关系中的使用。
另外,对于那些了解 SQL 的人来说。through属性/字段是您自定义中间表的方式,Django 自己创建的表,即through字段正在更改的内容。
Kev*_*nry 12
是的,使用显式through
表基本上消除了对a的需要ManyToManyField
.
拥有它的唯一真正好处是,如果您发现相关经理方便.就是这样:
group.members.all() # Persons in the group
Run Code Online (Sandbox Code Playgroud)
看起来比这更好:
Person.objects.filter(membership_set__group=group) # Persons in the group
Run Code Online (Sandbox Code Playgroud)
在实践中,我认为两者兼顾的主要原因是人们常常以平原开始ManyToManyField
; 意识到他们需要一些额外的数据并添加一个through
表格; 然后由于使用两个管理器的代码而导致两者都结束.
归档时间: |
|
查看次数: |
4438 次 |
最近记录: |