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
然后子类/混合这个管理员,只要它应该是一个只读管理员。
对于添加/删除,以及使它们的按钮消失,您可能还需要添加
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(查找或您的覆盖)返回 False,您将无法进入对象的更改视图 - 甚至不会显示指向它的链接。如果这样做实际上会很酷,并且默认的 get_readonly_fields() 检查更改权限并将所有字段设置为只读,如上所示。这样,非更改者至少可以浏览数据……鉴于当前的管理结构假定 view=edit,正如 jathanism 指出的那样,这可能需要在添加/更改/删除之上引入“查看”权限...
编辑:关于将所有字段设置为只读,也未经测试但看起来很有希望:
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]
))