为啥 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 管理员的 save() 覆盖中将站点添加到对象似乎不起作用?