多对多关联

时间:2013-07-23 03:27:59

标签: django foreign-keys many-to-many associations

我不明白为什么我们必须使用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()

这是对的吗?有什么区别?

1 个答案:

答案 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()方法可用于删除实例的所有多对多关系。

     

通过创建中间模型的实例建立多对多关系后,您可以发出查询。与普通的多对多关系一样,您可以使用多对多关系模型的属性进行查询。

     

来源:docs.djangoproject.com