中介模型

处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField 就可以了。但是,有时你可能需要关联数据到两个模型之间的关系上。

例如,有这样一个应用,它记录音乐家所属的音乐小组。我们可以用一个ManyToManyField 表示小组和成员之间的多对多关系。但是,有时你可能想知道更多成员关系的细节,比如成员是何时加入小组的。

对于这些情况,Django 允许你指定一个中介模型来定义多对多关系。 你可以将其他字段放在中介模型里面。源模型的ManyToManyField 字段将使用through 参数指向中介模型。对于上面的音乐小组的例子,代码如下:

既然你已经设置好ManyToManyField 来使用中介模型(在这个例子中就是Membership),接下来你要开始创建多对多关系。你要做的就是创建中介模型的实例:

ringo = Person.objects.create(name="Ringo Starr")
paul = Person.objects.create(name="Paul McCartney")
beatles = Group.objects.create(name="The Beatles")
m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.")
m1.save()
beatles.members.all()
[<Person: Ringo Starr>]
ringo.group_set.all()
[<Group: The Beatles>]
m2 = Membership.objects.create(person=paul, group=beatles,
... date_joined=date(1960, 8, 1),
... invite_reason="Wanted to form a band.")
beatles.members.all()
[<Person: Ringo Starr>, <Person: Paul McCartney>]


与普通的多对多字段不同,你不能使用add、 create和赋值语句(比如,beatles.members = [...])来创建关系:

THIS WILL NOT WORK

beatles.members.add(john)

NEITHER WILL THIS

beatles.members.create(name="George Harrison")

AND NEITHER WILL THIS

beatles.members = [john, paul, ringo, george]

为什么不能这样做? 这是因为你不能只创建 Person和 Group之间的关联关系,你还要指定 Membership模型中所需要的所有信息;而简单的add、create 和赋值语句是做不到这一点的。所以它们不能在使用中介模型的多对多关系中使用。此时,唯一的办法就是创建中介模型的实例。

 remove()方法被禁用也是出于同样的原因。但是clear() 方法却是可用的。它可以清空某个实例所有的多对多关系:

Beatles have broken up

beatles.members.clear()

Note that this deletes the intermediate model instances

Membership.objects.all()
[]


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField ...
    马小跳_阅读 1,361评论 0 0
  • 假设我们要记录乐手和他们所属的乐队。我们可以用一个 ManyToManyField 表示乐手和乐队之间的多对多关系...
    SingleDiego阅读 1,602评论 0 0
  • 原文:https://my.oschina.net/liuyuantao/blog/751438 查询集API 参...
    阳光小镇少爷阅读 3,858评论 0 8
  • 在关系数据库中设置表与表之间的关系 Many-to-one的关系 定义一个多对一的关系,用django.db.mo...
    低吟浅唱1990阅读 382评论 0 0
  • 青春是一张苍白的脸,我们奋力的梳妆打扮,最后只剩下苍老的容颜。 ——题记 有人说:既然选择了远方,便只顾风雨...
    花开半夏lmr阅读 278评论 0 1