Hi all,

I came across this ticket in stack overflow to try to find a solution for the 
issue of calling a signal only when a particular field on a model was updated.

https://stackoverflow.com/questions/39034798/django-signals-for-models-value-change-condition

I didn't want to use any third party libraries (especially one that had 
migrations on the DB) and wanted to use the built in signals provided by Django.

My initial solution is to:

1) Create the function I want to trigger when the particular field has changed 
(in the questioner's case the music field on the Album instance)

    def do_this_when_album_music_changed(sender, **kwargs):
        // do something
        print("I'm only going to be called if the field has changed")

2) Create the custom signal I want to send when the particular field changes

    album_music_changed = Signal(providing_args=[])

3) Create a pre_save signal receiver that will check whether or not the field 
has changed and "connect" the custom signal to the receiver, otherwise 
"disconnect" it

    @receiver(signal=signal=models.signals.pre_save, sender=Album)
    def album_pre_save(sender, instance, **kwargs):
        old_album = sender.objects.get(pk=instance.pk)
        if not old_album.music == instance.music:
            album_music_changed.connect(do_this_when_album_music_changed, 
sender=Album)
        else:
            album_music_changed.disconnect(do_this_when_album_music_changed, 
sender=Album)

4) Finally add a post_save signal that will actually send the trigger to call 
the custom signal and hence the function you want to run

    @receiver(signal=signal=models.signals.post_save, sender=Album)
    def album_post_save(sender, instance, **kwargs):
        album_music_changed.send(sender=sender)

In my case, I need to have the function run after post_save of the instance so 
this was the best thing I could come up with, if anyone has a better solution 
that would be awesome if you could share it.

Of course if you don't need the triggered function to run post_save and you are 
happy to run it pre_save you can just call the .send() inside the first "if" 
block and not have to worry about the post_save receiver

Omar

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/DF8CCA82-704A-4805-A16E-9D47096AA27E%40umda.net.

Reply via email to