Actions triggered by field change in Django

Django has a nifty feature called signals, which are effectively triggers that are set off at specific times:

  • Before/after a model's save method is called
  • Before/after a model's delete method is called
  • Before/after an HTTP request is made

Read the docs for full info, but all you need to do is create a receiver function and register it as a signal. This is usually done in models.py.

from django.core.signals import request_finished

def my_callback(sender, **kwargs):
    print "Request finished!"

request_finished.connect(my_callback)

Simple, eh?


It has been answered, but here's an example of using signals, post_init and post_save.

from django.db.models.signals import post_save, post_init

class MyModel(models.Model):
    state = models.IntegerField()
    previous_state = None

    @staticmethod
    def post_save(sender, instance, created, **kwargs):
        if instance.previous_state != instance.state or created:
            do_something_with_state_change()

    @staticmethod
    def remember_state(sender, instance, **kwargs):
        instance.previous_state = instance.state

post_save.connect(MyModel.post_save, sender=MyModel)
post_init.connect(MyModel.remember_state, sender=MyModel)

Basically, you need to override the save method, check if the state field was changed, set started if needed and then let the model base class finish persisting to the database.

The tricky part is figuring out if the field was changed. Check out the mixins and other solutions in this question to help you out with this:

  • Dirty fields in django