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
- Django, Apache2 on Google Kubernetes Engine writing Opencensus Traces to Stackdriver Trace
- Django override the form HTML label template?
- What's the difference between override_settings and modify_settings in Django?
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
- Get Celery to Use Django Test DB
- Adding per-object permissions to django admin
- Implementing UUID as primary key
- Where to instantiate boto s3 client so it is reused during a request?
- Django filter with OR condition using dict argument