[Fixed]-Django – disable model editing

15👍

Overwrite the save function for your model like so:

class MyModel(models.Model):

    def save(self, *args, **kwargs):

        if self.pk is None:
            super(MyModel, self).save(*args, **kwargs)

This function only call the superclass save function (which actually saves the change) if there is no pk, e.g. the model instance is new.

8👍

You could override your model class’s save() (do nothing if self.pk) and delete (always do nothing)

But really, the database level is the safest place for that. For example, in PostgreSQL you could write two simple rules:

CREATE RULE noupd_myapp_mymodel AS ON UPDATE TO myapp_mymodel
   DO NOTHING;
CREATE RULE nodel_myapp_mymodel AS ON DELETE TO myapp_mymodel
   DO NOTHING;

Either way, the admin wouldn’t know anything about this, so everything still looks editable. See my answer to Whole model as read-only for an attempt at making a model read-only in the admin. For your purposes, keep the add permission as-is, and only declare all fields read-only when not adding.

EDIT: One reason why overriding delete() in your model class is not safe, is the fact that “bulk delete” (Queryset.delete(), e.g. admin checkboxes action) will not call the individual instances’ delete() method, it will go straight to SQL: https://docs.djangoproject.com/en/dev/topics/db/queries/#deleting-objects

0👍

For those who need to prevent MyModel.objects.filter(pk=123).update(name="bob"):

class NoUpdateQuerySet(models.QuerySet):
    def update(self, *args, **kwargs):
        pass

class MyModel(models.Model):
    objects = NoUpdateQuerySet.as_manager()
    ...

Django docs – link

Leave a comment