Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 703
pseudosudo Avatar asked Jun 07 '12 17:06

pseudosudo


People also ask

What does save () return in Django?

1 and save() still returns None.

How do I save an object in Django?

To save changes to an object that's already in the database, use save() . This performs an UPDATE SQL statement behind the scenes. Django doesn't hit the database until you explicitly call save() .

How use Django save method?

Whenever one tries to create an instance of a model either from admin interface or django shell, save() function is run. We can override save function before storing the data in the database to apply some constraint or fill some ready only fields like SlugField.

What does Django objects get return?

It would return the object of your model on which you are querying. If nothing matches and no rows is returned, it would through a Model.


2 Answers

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.

like image 76
Andrew Gorcester Avatar answered Oct 07 '22 17:10

Andrew Gorcester


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

like image 31
John Lehmann Avatar answered Oct 07 '22 18:10

John Lehmann