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.
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.
- Django-allauth: how to properly use email_confirmed signal to set user to active
- Django 'ascii' codec can't encode character
- How to insert a row of data to a table using Django's ORM
- Python/Django "BadStatusLine" error
- Django Rest Framework using dot in url
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.
- Changes made to (static) CSS file not reflecting in Django development server
- How can I create a case-insensitive database index in Django?
- How to execute external script in the Django environment