ModelAdmin предоставляет ловушку get_readonly_fields () - следующее не проверено, моя идея состоит в том, чтобы определить все поля так, как это делает ModelAdmin, не сталкиваясь с рекурсией самих полей только для чтения:
from django.contrib.admin.util import flatten_fieldsets
class ReadOnlyAdmin(ModelAdmin):
def get_readonly_fields(self, request, obj=None):
if self.declared_fieldsets:
fields = flatten_fieldsets(self.declared_fieldsets)
else:
form = self.get_formset(request, obj).form
fields = form.base_fields.keys()
return fields
затем создайте подкласс / mixin для этого администратора, где бы он ни был администратором только для чтения.
Для добавления / удаления и исчезновения их кнопок, вы, вероятно, также захотите добавить
def has_add_permission(self, request):
# Nobody is allowed to add
return False
def has_delete_permission(self, request, obj=None):
# Nobody is allowed to delete
return False
P.S .: В ModelAdmin, если has_change_permission (lookup или your override) возвращает False, вы не получите представление об изменении объекта - и ссылка на него даже не будет показана. Было бы здорово, если бы это было так, и по умолчанию get_readonly_fields () проверил разрешение на изменение и в этом случае установил все поля только для чтения, как описано выше. Таким образом, неизменяющие могут, по крайней мере, просматривать данные ... учитывая, что текущая структура администратора предполагает view = edit, как указывает jathanism, это, вероятно, потребовало бы введения разрешения "view" поверх add / change / delete ...
РЕДАКТИРОВАТЬ: в отношении установки всех полей только для чтения, также не проверено, но выглядит многообещающе:
readonly_fields = MyModel._meta.get_all_field_names()
РЕДАКТИРОВАТЬ: Вот еще один
if self.declared_fieldsets:
return flatten_fieldsets(self.declared_fieldsets)
else:
return list(set(
[field.name for field in self.opts.local_fields] +
[field.name for field in self.opts.local_many_to_many]
))