我不明白为什么我们必须使用ManyToManyField来声明多对多的关联。为此,我将创建另一个带有两个外键的表,句号! 以下是文档https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany中的示例:
from django.db import models
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)
group = models.ForeignKey(Group)
extraField = models.DateField()
我只想写:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
extraField = models.DateField()
这是对的吗?有什么区别?
答案 0 :(得分:2)
为关系定义中间模型没有任何问题。这样,您可以在中间模型(成员资格)上存储额外信息,例如加入群组时,或者成员身份仍然有效。但是,大多数情况下,您不需要额外的信息,只想存储哪个人是哪个组的成员。在这些情况下,您可以使用简单的ManyToManyField
。 Django可以很容易地使用这些字段,因此您可以group.members.add(user)
和group.members.delete(user)
进行比较,将其与:
Membership.objects.create(user=user, group=group)
Membership.objects.get(user=user, group=group).delete()
免责声明:伪代码,可能无法正常工作
您仍然可以将ManyToManyField与中间模型一起使用,这允许大多数Django ManyToMany便利,但有一些限制:
与普通的多对多字段不同,您不能使用添加,创建或分配(即beatles.members = [...])来创建关系。
为什么呢?您不能只在Person和Group之间创建关系 - 您需要指定Membership模型所需关系的所有细节。简单的添加,创建和赋值调用不提供指定此额外细节的方法。因此,对于使用中间模型的多对多关系,它们被禁用。创建此类关系的唯一方法是创建中间模型的实例。
出于类似原因,remove()方法被禁用。但是,clear()方法可用于删除实例的所有多对多关系。
通过创建中间模型的实例建立多对多关系后,您可以发出查询。与普通的多对多关系一样,您可以使用多对多关系模型的属性进行查询。