为啥 django ORM 的`save` 方法不返回保存的对象?

Posted

技术标签:

【中文标题】为啥 django ORM 的`save` 方法不返回保存的对象?【英文标题】:Why does django ORM's `save` method not return the saved object?为什么 django ORM 的`save` 方法不返回保存的对象? 【发布时间】:2012-06-11 19:09:27 【问题描述】:

对此设计决策背后的推理有何见解?在我看来,让obj.save() 返回something,只有好处(如方法链接),没有缺点。

【问题讨论】:

【参考方案1】:

在 Python 中,让主要影响现有对象返回自身的函数通常被认为是一种很好的做法。例如,sorted(yourlist) 返回一个排序列表,但 yourlist.sort() 对列表进行就地排序并且不返回任何内容。

在一行上执行具有副作用的多个操作(与关注返回值的无副作用函数相反)并不是一个很好的做法。代码在行数方面会更紧凑,但会更难阅读,因为重要的副作用可能隐藏在链的中间。如果要使用方法链接,请在链的开头使用没有副作用的函数,然后在末尾使用具有副作用的单个函数,例如 .save()

换句话说,在方法链中,链的开头是输入,链的中间转换输入(向下导航树,对输入进行排序,更改字符串的大小写等)和链的末端是具有副作用的功能部分。如果您将具有副作用的方法埋在链的中间,那么您的方法链实际上做了什么就不清楚了。

【讨论】:

实际上 save() 返回保存的对象,也许它是 django 1.5 上的新对象? @maazza 我刚刚在 Django 1.5.1 上尝试过,但 save() 仍然返回 None。 The source code for the latest dev version 似乎也没有返回任何东西。 true , 我用了一个模型***.com/questions/7428245/… @maazza 哦,我明白了。我觉得这是一种不同的情况,因为您在表单上调用 .save() 并且它返回的是不同的对象,而不是自身。 FWIW 我认为如果 ModelForm 没有 .save() 而是有一种方法来实例化内存中的对象而没有副作用,就像 User() 实例化 User 对象一样,它会更干净。然后你可以调用 .save() 。但这只是我个人的看法,可能还有其他我没有考虑过的问题会妨碍我这样做。 这个答案可能是最好的,但如果你想返回一个对象,只需使用.save(commit=False)。 docs.djangoproject.com/en/dev/topics/forms/modelforms/…【参考方案2】:

这让我想起了最近在 Pycon2015 上 Greg Ward espoused 的一般原则,不要将函数与过程混淆。每个函数都应该返回一个值或有副作用,但不能两者兼而有之。

与 dict.update() 基本相同的问题is asked。

【讨论】:

【参考方案3】:

由于这是我在搜索“django return saved object”时得到的第一个结果,为了恭维 Andrew 的回答,如果您仍想返回已保存的对象,而不是使用:

ExampleModel(title=title).save()

返回无,你会使用:

saved_instance = ExampleModel.objects.create(title=title)

这是可行的,因为 ExampleModel.objects 是 Model Manager 而不是类的实例,所以它不会返回自身。

【讨论】:

以上是关于为啥 django ORM 的`save` 方法不返回保存的对象?的主要内容,如果未能解决你的问题,请参考以下文章

Kohana 3.2 - ORM 的 pk() 方法在 save() (create()) 之后返回 false - 为啥?

Django学习--ORM常用操作

为啥在 Django 管理员的 save() 覆盖中将站点添加到对象似乎不起作用?

django orm中objects.create()和object.save()的区别

Django之ORM操作

Django-ORM操作