相关对象引用¶
-
class
RelatedManager
¶ “相关管理器”是在一对多或多对多相关上下文中使用的管理器。这发生在两种情况:
ForeignKey
关系的“另一面”。那是:from django.db import models class Reporter(models.Model): # ... pass class Article(models.Model): reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
在上面的例子中,下面的方法将在经理
reporter.article_set
上可用。ManyToManyField
关系的两侧:class Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)
在此示例中,以下方法将在
topping.pizza_set
和pizza.toppings
上可用。
-
add
(*objs, bulk=True)¶ 将指定的模型对象添加到相关对象集。
例:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.add(e) # Associates Entry e with Blog b.
在上面的示例中,在
ForeignKey
关系的情况下,QuerySet.update()
用于执行更新。这需要已经保存对象。您可以使用
bulk=False
参数,而不是让相关管理器通过调用e.save()
来执行更新。然而,使用具有多对多关系的
add()
不会调用任何save()
方法,而是使用QuerySet.bulk_create()
创建关系。如果需要在创建关系时执行一些自定义逻辑,请听m2m_changed
信号。Changed in Django 1.9:添加了
bulk
参数。在旧版本中,外部密钥更新总是使用save()
完成。如果您需要旧的行为,请使用bulk=False
。
-
create
(**kwargs)¶ 创建一个新对象,保存它并将其放在相关对象集中。返回新创建的对象:
>>> b = Blog.objects.get(id=1) >>> e = b.entry_set.create( ... headline='Hello', ... body_text='Hi', ... pub_date=datetime.date(2005, 1, 1) ... ) # No need to call e.save() at this point -- it's already been saved.
这相当于(但要简单得多):
>>> b = Blog.objects.get(id=1) >>> e = Entry( ... blog=b, ... headline='Hello', ... body_text='Hi', ... pub_date=datetime.date(2005, 1, 1) ... ) >>> e.save(force_insert=True)
注意,不需要指定定义关系的模型的关键字参数。在上面的例子中,我们不将参数
blog
传递给create()
。 Django发现新的Entry
对象的blog
字段应该设置为b
。
-
remove
(*objs)¶ 从相关对象集中删除指定的模型对象:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
与
add()
类似,在上面的示例中调用e.save()
来执行更新。然而,使用具有多对多关系的remove()
将使用QuerySet.delete()
删除关系,这意味着没有模型save()
方法被调用;如果您希望在删除关系时执行自定义代码,请监听m2m_changed
信号。对于
ForeignKey
对象,此方法仅存在于null=True
。如果相关字段不能设置为None
(NULL
),则对象不能从关系中删除而不添加到另一个对象。在上述示例中,从b.entry_set()
中移除e
等效于执行e.blog = None
,并且因为blog
ForeignKey
不具有null=True
,所以这是无效的。对于
ForeignKey
对象,此方法接受bulk
参数以控制如何执行操作。如果使用True
(默认值),则使用QuerySet.update()
。如果是bulk=False
,则调用每个单独模型实例的save()
方法。这触发pre_save
和post_save
信号并且以性能为代价。
-
clear
()¶ 从相关对象集中删除所有对象:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()
注意,这不会删除相关对象 - 它只是取消它们。
与
remove()
一样,clear()
仅在ForeignKey
的位置可用,其中null=True
并且它也接受bulk
关键字参数。
-
set
(objs, bulk=True, clear=False)¶ - New in Django 1.9.
替换相关对象集:
>>> new_list = [obj1, obj2, obj3] >>> e.related_set.set(new_list)
此方法接受
clear
参数以控制如何执行操作。如果False
(默认值),则使用remove()
删除新集中缺失的元素,并且仅添加新的元素。如果clear=True
,则调用clear()
方法,并且立即添加整个集合。bulk
参数传递给add()
。注意,由于
set()
是复合操作,它受制于竞争条件。例如,可以在对clear()
的调用和对add()
的调用之间将新对象添加到数据库。
注解
注意,
add()
,create()
,remove()
,clear()
和set()
都对所有类型的相关字段立即应用数据库更改。换句话说,没有必要在关系的任一端调用save()
。此外,如果您使用 一个中间模型 进行多对多关系,那么将禁用
add()
,create()
,remove()
和set()
方法。
直接分配¶
相关对象集可以通过向其分配一个新的可迭代对象来批量替换一个操作:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
如果外键关系具有 null=True
,则相关管理器将在添加 new_list
的内容之前首先解除相关集中的任何现有对象。否则,new_list
中的对象将被添加到现有的相关对象集。
在早期版本中,直接赋值用于执行 clear()
,后跟 add()
。它现在执行带有关键字参数 clear=False
的 set()
。