Milano
Milano

Reputation: 18735

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.

Upvotes: 5

Views: 7194

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

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/

Upvotes: 12

phacic
phacic

Reputation: 1542

Yes you can use a post_save too. You should however remember signals are synchronous

Upvotes: -5

Related Questions