【Django文档转译】第2章:模型层——第2节:QuerySet(模块5: 访问关联的对象)

相关对象引用¶

班级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(*讣告, 体积=真)¶

将指定的模型对象添加到相关对象集。

例子:

>>> 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()在一个已经存在的关系上,不会复制这个关系,但它仍然会触发信号。

create(**)¶

创建一个新对象,保存它并将其放入相关的对象集中。返回新创建的对象:

>>> 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(*讣告, 体积=真)¶

从相关对象集中移除指定的模型对象:

>>> 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),则如果不将对象添加到另一个关系中,则无法从关系中移除对象。在上面的示例中,删除e从…b.entry_set()等于做e.blog = None,因为blog ForeignKey没有null=True这是无效的。

为ForeignKey对象时,此方法接受bulk参数来控制如何执行操作。如果True(违约),QuerySet.update()被利用了。如果bulk=False,save()方法,而是调用每个单独的模型实例的方法。这将触发pre_save和post_save以牺牲性能为代价。

对于多到多的关系,bulk关键字参数不存在。

clear(体积=真)¶

从相关对象集中移除所有对象:

>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()

注意,这并没有删除相关的对象–它只是断开了它们之间的关联。

就像remove(), clear()只有在ForeignKey在哪里null=True它还接受bulk关键字参数

对于多到多的关系,bulk关键字参数不存在。

set(奥比斯, 体积=真, 清楚=假)¶

替换一组相关对象:

>>> new_list = [obj1, obj2, obj3]
>>> e.related_set.set(new_list)

此方法接受clear参数来控制如何执行操作。如果False(默认值),新集合中缺少的元素将使用remove()只增加了新的。如果clear=True,clear()方法,然后立即添加整个集合。

为ForeignKey对象,bulk参数传递给add()和remove().

对于多到多的关系,bulk关键字参数不存在。

注意,自从set()是一种复合操作,它受种族条件的影响。例如,在调用clear()以及呼吁add().

注解

请注意add(), create(), remove(), clear(),和set()所有这些都会立即为所有类型的相关字段应用数据库更改。换句话说,没有必要打电话给save()在这段关系的两端。

而且,如果您正在使用中间模型对于多到多的关系,然后add(), create(), remove(),和set()方法被禁用。

如果你用prefetch_related(),add(), remove(), clear(),和set()方法清除预取缓存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值