How to update multiple fields in Django model efficiently?
The TLDR answer:
The first answer which you would get when you search
django model update on google you would find the
.update() Django ORM. While this is great, let us see few points about
.update() queryset -
pre_savesignals does not get triggered. While this might not be important for most of the users, but I have burnt my hand multiple times when I had a
post_savesignal configured to do few tasks on model data changes. And all of a sudden my code started to behave erratic.
- When to use
.update()- If you want to updated something which doesn't have signal defined.
- Performance oriented, since
updatequery would be using a single db query, while select and update does a round trip.
- Bulk update operation for entries
What are the alternatives you have if you want to use
update which would also trigger all the built-in model signals.
- Good old way. You can do a
filter/getquery and then manually update the fields using a loop or single update. But that is no fun, you didn't read the blog all the way till here so that I suggest you this right?
setattrcomes to rescue. If you are a newbie then you might not wondering what this does, if this is some special django queryset? No
setattris a python keyword which
sets the value of the attribute of an object.Whenever we want to update some model, we are dealing with python object so we can make use of
setattrto have a better pythonic version of the code.
Advantage of using the above method:
- Cleaner approach which is expandable. Lets say you have 10 different fields you don't have to worry have updating the fields manually
- All built-in model signals would be working as expected.
- Any new developer might not be able to read it at once, unless reads through what
setattrdoes in python.
- We are making 2 db calls, first one to get the data, second one to save the data.