标签:imp key [] model 框架 class ret foreign models
处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField 就可以了。但是,有时你可能需要关联数据到两个模型之间的关系上。
例如,有这样一个应用,它记录音乐家所属的音乐小组。我们可以用一个ManyToManyField 表示小组和成员之间的多对多关系。但是,有时你可能想知道更多成员关系的细节,比如成员是何时加入小组的。
对于这些情况,Django 允许你指定一个中介模型来定义多对多关系。 你可以将其他字段放在中介模型里面。源模型的ManyToManyField 字段将使用through 参数指向中介模型。对于上面的音乐小组的例子,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
from django.db import models class Person(models.Model): name = models.CharField(max_length = 128 ) def __str__( self ): # __unicode__ on Python 2 return self .name class Group(models.Model): name = models.CharField(max_length = 128 ) members = models.ManyToManyField(Person, through = ‘Membership‘ ) def __str__( self ): # __unicode__ on Python 2 return self .name class Membership(models.Model): person = models.ForeignKey(Person) group = models.ForeignKey(Group) date_joined = models.DateField() invite_reason = models.CharField(max_length = 64 ) |
既然你已经设置好ManyToManyField 来使用中介模型(在这个例子中就是Membership),接下来你要开始创建多对多关系。你要做的就是创建中介模型的实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
>>> 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 = [...])来创建关系:
1
2
3
4
5
6
|
# 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() 方法却是可用的。它可以清空某个实例所有的多对多关系:
1
2
3
4
5
|
>>> # Beatles have broken up >>> beatles.members.clear() >>> # Note that this deletes the intermediate model instances >>> Membership.objects. all () [] |
标签:imp key [] model 框架 class ret foreign models
原文地址:https://www.cnblogs.com/hanbowen/p/9567438.html