Eu escrevi uma classe genérica para lidar com a visualização ReadOnly dependendo das permissões do usuário, incluindo inlines;)
Em models.py:
class User(AbstractUser):
...
def is_readonly(self):
if self.is_superuser:
return False
adminGroup = Group.objects.filter(name="admins")
if adminGroup in self.groups.all():
return False
return True
Em admin.py:
class ReadOnlyAdmin(admin.ModelAdmin):
def __init__(self, *args, **kwargs):
self._init_readonly_fields = self.readonly_fields
for inline in self.inlines:
inline._init_readonly_fields = inline.readonly_fields
super().__init__(*args,**kwargs)
def change_view( self, request, object_id, form_url='', extra_context=None ):
context = extra_context or {}
if request.user.is_readonly():
self.readonly_fields = [ field.name for field in self.model._meta.get_fields() if not field.auto_created ]
for inline in self.inlines:
inline.readonly_fields = [field.name for field in inline.model._meta.get_fields() if not field.auto_created]
self.save_on_top = False
context['show_save'] = False
context['show_save_and_continue'] = False
else:
self.readonly_fields = self._init_readonly_fields
for inline in self.inlines:
inline.readonly_fields = self._init_readonly_fields
return super().change_view(
request, object_id, form_url, context )
def save_model(self, request, obj, form, change):
if request.user.is_readonly():
return False
return super().save_model( request, obj, form, change )
Então, podemos apenas herdar normalmente nossas classes em admin.py:
class ContactAdmin(ReadOnlyAdmin):
list_display = ("name","email","whatever")
readonly_fields = ("updated","created")
inlines = ( PhoneInline, ... )