How can I make a model completely read-only in the admin interface? It\'s for a kind of log table, where I\'m using the admin features to search, sort, filter etc, but there
If you want the user become aware that he/she cannot edit it, 2 pieces are missing on the first solution. You have remove the delete action!
class MyAdmin(ModelAdmin)
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def get_actions(self, request):
actions = super(MyAdmin, self).get_actions(request)
if 'delete_selected' in actions:
del actions['delete_selected']
return actions
Second: the readonly solution works fine on plain models. But it does NOT work if you have an inherited model with foreign keys. Unfortunately, I don't know the solution for that yet. A good attempt is:
Whole model as read-only
But it does not work for me either.
And a final note, if you want to think on a broad solution, you have to enforce that each inline has to be readonly too.
The admin is for editing, not just viewing (you won't find a "view" permission). In order to achieve what you want you'll have to forbid adding, deleting, and make all fields readonly:
class MyAdmin(ModelAdmin):
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
(if you forbid changing you won't even get to see the objects)
For some untested code that tries to automate setting all fields read-only see my answer to Whole model as read-only
EDIT: also untested but just had a look at my LogEntryAdmin and it has
readonly_fields = MyModel._meta.get_all_field_names()
Don't know if that will work in all cases.
EDIT: QuerySet.delete() may still bulk delete objects. To get around this, provide your own "objects" manager and corresponding QuerySet subclass which doesn't delete - see Overriding QuerySet.delete() in Django