Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identify the changed fields in django post_save signal

I'm using django's post_save signal to execute some statements after saving the model.

class Mode(models.Model):     name = models.CharField(max_length=5)     mode = models.BooleanField()   from django.db.models.signals import post_save from django.dispatch import receiver  @receiver(post_save, sender=Mode) def post_save(sender, instance, created, **kwargs):         # do some stuff         pass 

Now I want to execute a statement based on whether the value of the mode field has changed or not.

@receiver(post_save, sender=Mode) def post_save(sender, instance, created, **kwargs):         # if value of `mode` has changed:         #  then do this         # else:         #  do that         pass 

I looked at a few SOF threads and a blog but couldn't find a solution to this. All of them were trying to use the pre_save method or form which are not my use case. https://docs.djangoproject.com/es/1.9/ref/signals/#post-save in the django docs doesn't mention a direct way to do this.

An answer in the link below looks promising but I don't know how to use it. I'm not sure if the latest django version supports it or not, because I used ipdb to debug this and found that the instance variable has no attribute has_changed as mentioned in the below answer.

Django: When saving, how can you check if a field has changed?

like image 848
Wendy Avatar asked Apr 19 '16 13:04

Wendy


People also ask

What are the signals in Django?

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.

What is the use of the Post_delete signal in Django?

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.

Are Django signals synchronous?

Like most of Django, they are fully "synchronous".


1 Answers

Ussually it's better to override the save method than using signals.

From Two scoops of django: "Use signals as a last resort."

I agree with @scoopseven answer about caching the original value on the init, but overriding the save method if it's possible.

class Mode(models.Model):     name = models.CharField(max_length=5)     mode = models.BooleanField()     __original_mode = None      def __init__(self, *args, **kwargs):         super(Mode, self).__init__(*args, **kwargs)         self.__original_mode = self.mode      def save(self, force_insert=False, force_update=False, *args, **kwargs):         if self.mode != self.__original_mode:             #  then do this         else:             #  do that          super(Mode, self).save(force_insert, force_update, *args, **kwargs)         self.__original_mode = self.mode 
like image 191
educolo Avatar answered Sep 21 '22 22:09

educolo