Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Actions triggered by field change in Django

How do I have actions occur when a field gets changed in one of my models? In this particular case, I have this model:

class Game(models.Model):     STATE_CHOICES = (         ('S', 'Setup'),         ('A', 'Active'),         ('P', 'Paused'),         ('F', 'Finished')         )     name = models.CharField(max_length=100)     owner = models.ForeignKey(User)     created = models.DateTimeField(auto_now_add=True)     started = models.DateTimeField(null=True)     state = models.CharField(max_length=1, choices=STATE_CHOICES, default='S') 

and I would like to have Units created, and the 'started' field populated with the current datetime (among other things), when the state goes from Setup to Active.

I suspect that a model instance method is needed, but the docs don't seem to have much to say about using them in this manner.

Update: I've added the following to my Game class:

    def __init__(self, *args, **kwargs):         super(Game, self).__init__(*args, **kwargs)         self.old_state = self.state      def save(self, force_insert=False, force_update=False):         if self.old_state == 'S' and self.state == 'A':             self.started = datetime.datetime.now()         super(Game, self).save(force_insert, force_update)         self.old_state = self.state 
like image 698
Jeff Bradberry Avatar asked Jul 29 '09 01:07

Jeff Bradberry


People also ask

How do I update a specific field in Django?

Use update_fields in save() If you would like to explicitly mention only those columns that you want to be updated, you can do so using the update_fields parameter while calling the save() method. You can also choose to update multiple columns by passing more field names in the update_fields list.

What are triggers in Django?

Django Triggers is a light-weight framework for having one part of an application generate a trigger while another part responds to to it. Triggers are persistent and can be scheduled to be processed at a later time.

What is Onetoone field in Django?

This field can be useful as a primary key of an object if that object extends another object in some way. For example – a model Car has one-to-one relationship with a model Vehicle, i.e. a car is a vehicle. One-to-one relations are defined using OneToOneField field of django.


1 Answers

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) 
like image 79
Daniel Backman Avatar answered Sep 22 '22 18:09

Daniel Backman