2

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

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

4

1 回答 1

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 模型所需的关系的所有细节。简单的 add、create 和 assignment 调用不提供指定这些额外细节的方法。因此,对于使用中间模型的多对多关系,它们被禁用。创建这种类型的关系的唯一方法是创建中间模型的实例。

由于类似的原因, remove() 方法被禁用。但是,clear() 方法可用于删除实例的所有多对多关系。

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

来源:docs.djangoproject.com

于 2013-07-23T06:52:54.790 回答