Search code examples
pythondjangodjango-modelsdjango-signalsdjango-database

Detect field change using post_save instead of pre_save signal


I need to do some actions when one field has changed.

Since this action needs to work with already saved object, I can't use pre_save signal like this:

@receiver(pre_save, sender=reservation_models.Reservation)
def generate_possible_pairs(sender, instance, **kwargs):
    try:
        reservation_old = sender.objects.get(pk=instance.pk)
    except sender.DoesNotExist:
        pass # Object is new, so field hasn't technically changed, but you may want to do something else here.
    else:
        if not reservation_old.datetime == instance.datetime: # Field has changed
            do_something(instance) # It would be better to be sure instance has been saved

Is it possible to use post_save signal for this?

I would like to avoid adding temporary attributes to this model.


Solution

  • Using the post_save signal you won't be able to retrieve the previous state from db - But why use a signal at all ?

    class Reservation(models.Model):
        def save(self, *args, **kw):
            old = type(self).objects.get(pk=self.pk) if self.pk else None
            super(Reservation, self).save(*args, **kw)
            if old and old.datetime != self.datetime: # Field has changed
                do_something(self)
    

    You may also want to read this : https://lincolnloop.com/blog/django-anti-patterns-signals/