Home > Software engineering >  Django How to cleaify if the value is changed in models save method
Django How to cleaify if the value is changed in models save method

Time:08-24

I have a model like this one:

class Exam(BaseModel):
    ...
    STATE_CHOICES = (
        (PASS, PASS),
        (FAILED, FAILED),
        (GREAT, GREAT),
    state = models.CharField(max_length=15, choices=STATE_CHOICES, default=PASS)
    ...

Now I want orderride the save method and know if the state field is changed or not:

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        if self.__state != self.state:
            print('changed')
        super().save(force_insert, force_update, using, update_fields)

The self.__state seems wrong, how can I do that?

CodePudding user response:

Essentially, you want to override the init method of models.Model so that you keep a copy of the original value. This makes it so that you don't have to do another DB lookup (which is always a good thing).

class Exam(models.Model):
    STATE_CHOICES = (
    ("PASS", "PASS"),
    ("FAILED", "FAILED"),
    ("GREAT", "GREAT"),)
    state = models.CharField(max_length=15, choices=STATE_CHOICES, default="PASS")

    __original_state = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__original_state = self.state

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        if self.state != self.__original_state:
            print("changed")
            # state changed - do something here

        super().save(force_insert, force_update, *args, **kwargs)
        self.__original_state = self.state

CodePudding user response:

This question has been thoroughly solved and discussed in this thread including the edge cases, limitations and benefits of each approach.

  • Related