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
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.
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.
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().