所以这里我将使用经典的Django博客和文档中的条目模型(link)。我在条目的blog属性中添加了null=True
。在
>>> cb = Blog.objects.get(name__startswith="Cheese")
>>> gouda = Entry.objects.get(headline__startswith="Gouda")
>>> cb.entry_set.all()
[<Entry: Gouda>, <Entry: Emmentaler>]
>>> cb.entry_set.remove(gouda)
>>> gouda.blog
<Blog: Cheese blog>
我知道数据库中的一切都很好并且更新了,如果我再次查询示例中的第二行,gouda.blog
将返回{gouda.blog
就不是{
编辑:
所以,如果我对每件事都理解正确,这就是它的工作原理:
>>> cb = Blog.objects.get(name__startswith="Cheese")
>>> gouda = Entry.objects.get(headline__startswith="Gouda")
>>> cb.entry_set.all()
[<Entry: Gouda>, <Entry: Emmentaler>]
>>> cb.entry_set.remove(gouda)
>>> gouda.blog
<Blog: Cheese blog>
所以remove()
方法的bulk
参数的默认值是True
。这意味着将使用QuerySet.update()
。对象gouda
不会在Python级别更改,因此blog
属性仍将保留“Cheese blog”博客的主键。当我们查询gouda.blog
时,我们仍然会得到“Cheese blog”对象。在
但是当bulk=False
被传递给remove()
时会发生什么呢?来自文档:如果bulk=False,则调用每个单独模型实例的save()方法。在
然后我重写save()
模型的save()
方法,如下所示:
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self.blog == None:
print(id(self))
然后:
>>> cb = Blog.objects.get(name__startswith="Cheese")
>>> gouda = Entry.objects.get(headline__startswith="Gouda")
>>> cb.entry_set.all()
[<Entry: Gouda>, <Entry: Emmentaler>]
>>> id(gouda)
139797518743592
>>> cb.entry_set.remove(gouda, bulk=False)
139797518745552
>>> gouda.blog
<Blog: Cheese blog>
现在我们看到,调用save()
方法的gouda
对象与shell中的对象不相同,因此shell中的对象在其blog
属性中仍然保留“Cheese blog”的主键。当我们用gouda.blog
查询blog时,我们仍然得到“Cheese blog”对象。在
这是正确的吗?如果是,为什么我们传递给remove()
的同一个对象上没有调用{
你自己也说过,你需要回到数据库去获取新的信息。
gouda
对象不会自动保留到其数据库行的链接;它只在被告知这样做时才查询它。在相关问题 更多 >
编程相关推荐