[Fixed]-Can I make a django model object immutable?

16πŸ‘

I know this question is pretty old, but is very much still relevant.

The best, if somewhat curt solution I’ve come up with to date looks like so:

class ModelName(models.Model):
    # fields, etc...
    def save(self, *args, **kwargs):
        if self.pk:
            raise ValidationError("you may not edit an existing %s" % self._meta.model_name)
        super(ModelName, self).save(*args, **kwargs)

This way users are informed that the action they are performing is unsupported, rather than just silently failing.

πŸ‘€pnovotnak

6πŸ‘

The easiest thing to do here, if you are trying to make your instance immutable, is to write a little wrapper:

def _model_save_base(*args, **kwargs):
    raise NotImplementedError("Cannot save a frozen instance.")

def freeze_instance(obj):
    obj.save_base = _model_save_base

Then you can call freeze_instance on your object:

blog = Blog.objects.get(name='Django')
blog.save()  # writes to the database
freeze_instance(blog)
blog.save()  # NotImplementedError

You can always improve this by making a custom exception. Or you can add freeze_instance to your Blog model. But that’s mostly stylistic.

πŸ‘€Simon Law

4πŸ‘

Overriding the save() method of a normal model in such a manner can be troublesome, so you should consider using a proxy model with a save() method that throws an exception if called.

1πŸ‘

There are also a few libraries out there, like django-immutablemodel and django-immutablefield that provide a more comprehensive api for immutable models.

πŸ‘€jstaab

Leave a comment