Django How to cleaify if the value is changed in models save method

Question:

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?

Asked By: Mehdi Aria

||

Answers:

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
Answered By: ilyasbbu

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

Answered By: FAYEMI BOLUWATIFE

There is no need to write this yourself. Use the Fieldtracker from the model_utils package to check if data has changed: https://django-model-utils.readthedocs.io/en/latest/utilities.html#field-tracker

Answered By: hendrikschneider
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.