Why does django ORM's `save` method not return the saved object?

前端 未结 3 789
离开以前
离开以前 2020-12-09 07:11

Any insight into the reasoning behind this design decision? It seems to me that having obj.save() return something, has only benefits (like method chai

相关标签:
3条回答
  • 2020-12-09 07:59

    It's generally considered good practice in Python to have functions that primarily affect existing objects not return themselves. For instance, sorted(yourlist) returns a sorted list but yourlist.sort() sorts the list in-place and does not return anything.

    Performing multiple operations with side-effects (as opposed to no-side-effect functions where the focus is on the return value) on a single line is not really good practice. The code will be more compact in terms of number of lines, but it will be harder to read because important side-effects may be buried in the middle of a chain. If you want to use method chaining, use functions with no side effects in the beginning of the chain and then have a single function with a side effect like .save() at the end.

    To put it another way, in a method chain, the beginning of the chain is the input, the middle of the chain transforms the input (navigating down a tree, sorting the input, changing case of a string etc) and the end of the chain is the functional part that does work with side-effects. If you bury methods with side-effects in the middle of the chain then it will be unclear what your method chain actually does.

    0 讨论(0)
  • 2020-12-09 08:15

    Since this is the first result that I get when searching for "django return saved object", to compliment Andrew's answer, if you still want to return the saved object, instead of using:

    ExampleModel(title=title).save()
    

    which returns None, you'd use:

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

    And this works because ExampleModel.objects is a Model Manager rather than an instance of the class, so it's not returning itself.

    0 讨论(0)
  • 2020-12-09 08:16

    This reminds me of the general principle that Greg Ward espoused at Pycon2015 recently, not to confuse functions with procedures. Every function should return a value or have a side-effect, but not both.

    Basically the same question is asked of dict.update().

    0 讨论(0)
提交回复
热议问题