[Django]-Why does django ORM's `save` method not return the saved object?

74👍

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.

8👍

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

5👍

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.

Leave a comment