Actions triggered by field change in Django

后端 未结 7 1036
囚心锁ツ
囚心锁ツ 2020-12-07 23:09

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         


        
7条回答
  •  太阳男子
    2020-12-07 23:17

    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

提交回复
热议问题