[Django]-Django trigger post_save on update()

18👍

The problem you’ll have by doing this is that .update() doesn’t have to load the objects from the database in order to do its thing. Consider this example on a users table with 1 million rows:

users = User.objects.filter(date_joined__lte=now() - timedelta(days=30)
users.update(is_active=False)

What django will do here is not load potentially hundreds of thousands of rows from your database, just to set is_active to False, then save each row individually, but instead issue an UPDATE command via the database engine directly: UPDATE users SET is_active=False WHERE date_joined < 30_DAYS_AGO. This is the sole reason Django does not trigger post_save on update: because it hasn’t loaded anything from the database in the first place.

In order for it to trigger the signal, it would need to load all those objects from the database, issue a database query UPDATE users SET is_active=False WHERE id=X thousands of times, once for each row, then send the signal. Which would kill performance.

If you really want to use the signal, you will need to load the objects from the database, iterate over them and save them one at a time. There’s no way around this unfortunately.

-4👍

save() method is called whenever Django model object is created or updated.

ex:
Creating a new user profile,
Updating existing user profile.

We can use Django signals to send mails to notify the user for these two scenarios.

For this we use Django built in signal post_save.

post_signal will be dispatched whenever .save() is called on Django model instance.

we can use below code in models.py:

from django.db.models import signals
from django.dispatch import receiver
@receiver(signals.post_save, sender=Customer)
def on_create_or_updated_obj(sender, instance, **kwargs):
   if kwargs['created']:
      print 'obj created'
      #send user created email to user
   else:
      print 'obj updated'
      #logic for sending user updated email to user

Leave a comment