Some points to consider when choosing between Django signals or overriding model
.save()
method to perform additional tasks when writing into databases.These are not golden rules but for reference only.
Override .save()
when
- Model values must be modified or transformed before saving into the database. Do it in
.save()
so it won’t fail. - The manipulation applies to the model instance itself, instead of side-effects to other objects.
- For better readability as codes are placed together. The business logic in
.save()
stays closely with the model definitions.
Use Django signals when
- Model values can be saved safely without intervention or clean up, so no need to customize
.save()
and move the business logic to signal handlers. - Having side-effects to other objects like updating multiple model instances
- Decoupling codes across modules
- For better code reusability, apply the same signal handler to multiple models.
- Extending or interacting with 3rd party package, where overriding or monkey patching the
.save()
method of the imported models is not possible. - The codes need to be executed when calling either
instance.delete()
orqueryset.delete()
. Both methods emit thepre_delete
andpost_delete
signals, whilequeryset.delete()
does not invoke the model’s.delete()
method.
(Note: this is not true forqueryset.update()
which does not emit thepre_save
orpost_save
signals, nor does it callinstance.save()
method)