“相关经理”是一对多或多对多相关上下文中使用的经理。这在两种情况下发生:
A的“另一面” ForeignKey
关系。即:
from django.db import models
class Blog(models.Model):
# ...
pass
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)
在上面的示例中,管理器上将提供以下方法 blog.entry_set
。
一张纸的两面 ManyToManyField
关系::
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
在这个例子中,下面的方法在 topping.pizza_set
以及在 pizza.toppings
.
Asynchronous version : aadd
将指定的模型对象添加到相关对象集。
示例:
>>> 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()
方法(方法) bulk
参数不存在),而是使用 QuerySet.bulk_create()
. 如果在创建关系时需要执行一些自定义逻辑,请侦听 m2m_changed
信号,将触发 pre_add
和 post_add
行动。
使用 add()
对于已经存在的关系,不会复制该关系,但它仍然会触发信号。
多对多关系 add()
接受模型实例或字段值(通常是主键)作为 *objs
争论。
使用 through_defaults
用于指定新的 intermediate model 实例,如果需要。可以在 through_defaults
在创建任何中间实例之前,它们将被计算一次。
Asynchronous version : acreate
创建一个新对象,将其保存并放入相关对象集中。返回新创建的对象:
>>> 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
.
使用 through_defaults
用于指定新的 intermediate model 实例,如果需要的话。可以在 through_defaults
字典。
Asynchronous version : aremove
从相关对象集中删除指定的模型对象:
>>> 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
如果您希望在删除关系时执行自定义代码,则发出信号。
多对多关系 remove()
接受模型实例或字段值(通常是主键)作为 *objs
争论。
为了 ForeignKey
对象,此方法仅在 null=True
. 如果相关字段不能设置为 None
(NULL
,则无法从关系中删除对象而不将其添加到另一个关系中。在上面的示例中,删除 e
从 b.entry_set()
相当于做 e.blog = None
因为 blog
ForeignKey
没有 null=True
,这是无效的。
为了 ForeignKey
对象,此方法接受 bulk
用于控制如何执行操作的参数。如果 True
(违约), QuerySet.update()
使用。如果 bulk=False
, the save()
而是调用每个单独模型实例的方法。这会触发 pre_save
和 post_save
以牺牲性能为代价发出信号。
对于多对多关系, bulk
关键字参数不存在。
Asynchronous version : aclear
从相关对象集中删除所有对象:
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
注意,这不会删除相关的对象——它只是解除它们的关联。
就像 remove()
, clear()
仅在上可用 ForeignKey
在哪里 null=True
它也接受 bulk
关键字参数。
对于多对多关系, bulk
关键字参数不存在。
Asynchronous version : aset
替换相关对象集:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)
此方法接受 clear
用于控制如何执行操作的参数。如果 False
(默认值),使用 remove()
只添加了新的。如果 clear=True
, the clear()
方法,并立即添加整个集。
为了 ForeignKey
对象 bulk
参数传递到 add()
和 remove()
.
对于多对多关系, bulk
关键字参数不存在。
请注意,自 set()
是一种复合操作,受比赛条件限制。例如,在调用 clear()
呼唤 add()
.
多对多关系 set()
接受模型实例或字段值(通常是主键)的列表,作为 objs
争论。
使用 through_defaults
用于指定新的 intermediate model 实例,如果需要。可以在 through_defaults
在创建任何中间实例之前,它们将被计算一次。
备注
请注意 add()
, aadd()
, create()
, acreate()
, remove()
, aremove()
, clear()
, aclear()
, set()
, and aset()
all apply database changes immediately for all types of related fields. In other words, there is no need to call save()
/asave()
在这段关系的两端。
如果您使用 prefetch_related()
vt.的. add()
, aadd()
, remove()
, aremove()
, clear()
, aclear()
, set()
,以及 aset()
方法清除预取的缓存。