I see I can override or define pre_save, save, post_save
to do what I want when a model instance gets saved.
Which one is preferred in which situation and why?
pre_save) is provoked just before the model save() method is called, or you could say model save method is called only after pre_save is called and done its job free of errors.
In the example above, save_profile is our receiver function, User is the sender and post_save is the signal. You can read it as: Everytime when a User instance finalize the execution of its save method, the save_profile function will be executed. If you supress the sender argument like this: post_save.
Django Signals - post_delete()To notify another part of the application after the delete event of an object happens, you can use the post_delete signal.
Django includes a “signal dispatcher” which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place.
I shall try my best to explain it with an example:
pre_save
and post_save
are signals that are sent by the model. In simpler words, actions to take before or after the model's save
is called.
A save
triggers the following steps
Django does provide a way to override these signals.
Now,
pre_save
signal can be overridden for some processing before the actual save into the database happens - Example: (I dont know a good example of where pre_save
would be ideal at the top of my head)
Lets say you have a ModelA
which stores reference to all the objects of ModelB
which have not been edited yet. For this, you can register a pre_save
signal to notify ModelA
right before ModelB
's save
method gets called (Nothing stops you from registering a post_save
signal here too).
Now, save
method (it is not a signal) of the model is called - By default, every model has a save
method, but you can override it:
class ModelB(models.Model): def save(self): #do some custom processing here: Example: convert Image resolution to a normalized value super(ModelB, self).save()
Then, you can register the post_save
signal (This is more used that pre_save
)
A common usecase is UserProfile
object creation when User
object is created in the system.
You can register a post_save
signal which creates a UserProfile
object that corresponds to every User
in the system.
Signals are a way to keep things modular, and explicit. (Explicitly notify ModelA
if i save
or change something in ModelB
)
I shall think of more concrete realworld examples in an attempt to answer this question better. In the meanwhile, I hope this helps you
pre_save
it's used before the transaction saves.
post_save
it's used after the transaction saves.
You can use pre_save
for example if you have a FileField
or an ImageField
and see if the file
or the image
really exists.
You can use post_save
when you have an UserProfile
and you want to create a new one at the moment a new User
it's created.
Don't forget about recursions risk. If you use post_save method with instance.save() calling, instead of .update method, you should disconnect your post_save signal:
Signal.disconnect(receiver=None, sender=None, dispatch_uid=None)[source] To disconnect a receiver from a signal, call Signal.disconnect(). The arguments are as described in Signal.connect(). The method returns True if a receiver was disconnected and False if not.
The receiver argument indicates the registered receiver to disconnect. It may be None if dispatch_uid is used to identify the receiver.
... and connect it again after.
update() method don't send pre_ and post_ signals, keep it in mind.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With