How do I know if an instance of a django model has been modified?

I have a code like this:

# ...
obj = Model.objects.get(pk=2342)
if foo:
    obj.foo = 'bar'
if bar:
    obj.bar = 'baz'
obj.save()

Is there a good way to find out if a model instance has been modified to prevent it from being saved each time the code is run?

+5
source share
4 answers

A typical template is to do something like:

model = Model.objects.get(pk=2342)
dirty = False
if foo:
    model.foo = 'bar'
    dirty = True
if bar:
    model.bar = 'baz'
    dirty = True

if dirty:
    model.save()
+4
source

Just disassemble the “snapshot” instance with the current model instance by field, you can get snapshotthrough copy.copy(obj)or model_cls.objects.get(pk=obj.pk).

Also you can simply compare the dumped versions:

from django.core.serializers.json import Serializer
dump = Serializer.serialize([obj])
...
changed = dump == Serializer.serialize([obj])

Typically, setting up your code is easiest:

obj = Model.objects.get(pk=2342) # 'obj' is better than 'model', IMO
changed = False
if foo:
    ...
    obj.foo = 'bar'
    changed = True
if bar:
    ...
    obj.bar = 'baz'
    changed = True
if changed:
    obj.save()    
+1
source

Django . sql , .

UPDATE

. . - .

0

To do this in a more abstract way, see the documentation for the model method from_db(), which is called when loading data into the model instance from the database. With this method, you can cache the original value of a field when it is loaded, and then compare it with the current value in the method save().

Example (note, I did not check this code):

class SaveIfModified(models.Model):
    foo = models.TextField()

    @classmethod
    def from_db(cls, db, field_names, values):
        instance = super()
        # caveat: deferred values won't appear here
        if "foo" in field_names:
            instance._foo = values[field_names.index("foo")]
        return instance

    def save(self, *args, **kwargs):
        if self.foo == self._foo:
            return
        super().save(*args, **kwargs)
0
source

All Articles