web-dev-qa-db-ja.com

Django ORMの `save`メソッドが保存されたオブジェクトを返さないのはなぜですか?

この設計上の決定の背後にある理由についての洞察はありますか? obj.save() return somethingを使用することには、利点(メソッドチェーンなど)のみがあり、欠点はないように思われます。

36
garageàtrois

Pythonでは、主に既存のオブジェクトに影響を与える関数を使用することをお勧めしますnot自分自身を返します。たとえば、sorted(yourlist)は並べ替えられたリストを返しますが、 yourlist.sort()はリストをインプレースでソートし、何も返しません。

1行で(戻り値に焦点が当てられている副作用のない関数とは対照的に)副作用のある複数の操作を実行することは、実際には良い習慣ではありません。コードは行数の点でよりコンパクトになりますが、重要な副作用がチェーンの途中に埋もれてしまう可能性があるため、読みにくくなります。メソッドチェーンを使用する場合は、チェーンの最初に副作用のない関数を使用し、最後に.save()のような副作用のある単一の関数を使用します。

言い換えると、メソッドチェーンでは、チェーンの先頭が入力であり、チェーンの中央が入力を変換し(ツリーのナビゲート、入力の並べ替え、文字列の大文字と小文字の変更など)、チェーンは、副作用を処理する機能部分です。チェーンの途中に副作用のあるメソッドを埋めると、メソッドチェーンが実際に何をするのかが不明確になります。

57

これは、最近のPycon2015でGreg Ward espoused であり、関数とプロシージャを混同しないという一般原則を思い出させます。すべての関数は値を返すか、副作用がありますが、両方ではありません。

基本的に同じ質問 尋ねられます dict.update()の。

4
John Lehmann

これは「Djangoreturnsaved object」を検索したときに最初に得られる結果なので、Andrewの答えを補完するために、次を使用する代わりに、保存されたオブジェクトを返したい場合は、

ExampleModel(title=title).save()

noneを返す場合は、次を使用します。

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

そして、これはExampleModel.objectsはクラスのインスタンスではなく モデルマネージャー であるため、それ自体は返されません。

0
Amr Awad