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_C
One way is to add a setter for the state. It's just a normal method, nothing special.
class Game(models.Model):
# ... other code
def set_state(self, newstate):
if self.state != newstate:
oldstate = self.state
self.state = newstate
if oldstate == 'S' and newstate == 'A':
self.started = datetime.now()
# create units, etc.
Update: If you want this to be triggered whenever a change is made to a model instance, you can (instead of set_state
above) use a __setattr__
method in Game
which is something like this:
def __setattr__(self, name, value):
if name != "state":
object.__setattr__(self, name, value)
else:
if self.state != value:
oldstate = self.state
object.__setattr__(self, name, value) # use base class setter
if oldstate == 'S' and value == 'A':
self.started = datetime.now()
# create units, etc.
Note that you wouldn't especially find this in the Django docs, as it (__setattr__
) is a standard Python feature, documented here, and is not Django-specific.
note: Don't know about versions of django older than 1.2, but this code using __setattr__
won't work, it'll fail just after the second if
, when trying to access self.state
.
I tried something similar, and I tried to fix this problem by forcing the initialization of state
(first in __init__
then ) in __new__
but this will lead to nasty unexpected behaviour.
I'm editing instead of commenting for obvious reasons, also: I'm not deleting this piece of code since maybe it could work with older (or future?) versions of django, and there may be another workaround to the self.state
problem that i'm unaware of