如何在管理界面中使模型完全只读?这是针对一种日志表的情况,我使用管理功能进行搜索、排序、过滤等操作,但没有必要修改日志。
如果看起来像一个重复的问题,那么这不是我想做的:
- 我不是在寻找只读字段(即使将每个字段设为只读,仍然可以创建新记录)
- 我不是在创建只读用户:每个用户都应该是只读的。
如何在管理界面中使模型完全只读?这是针对一种日志表的情况,我使用管理功能进行搜索、排序、过滤等操作,但没有必要修改日志。
如果看起来像一个重复的问题,那么这不是我想做的:
接受的答案应该是可行的,但这也将保留只读字段的显示顺序。使用此解决方案,您也不必硬编码模型。
class ReadonlyAdmin(admin.ModelAdmin):
def __init__(self, model, admin_site):
super(ReadonlyAdmin, self).__init__(model, admin_site)
self.readonly_fields = [field.name for field in filter(lambda f: not f.auto_created, model._meta.fields)]
def has_delete_permission(self, request, obj=None):
return False
def has_add_permission(self, request, obj=None):
return False
当我需要让某些用户在Django管理页面中所有字段只读时,遇到了相同的要求。最终,我利用了Django模块“django-admin-view-permission”,而不是编写自己的代码。如果您需要更精细的控制以明确定义哪些字段,则需要扩展该模块。您可以在此处查看插件的演示。
class User(AbstractUser):
...
def is_readonly(self):
if self.is_superuser:
return False
# make readonly all users not in "admins" group
adminGroup = Group.objects.filter(name="admins")
if adminGroup in self.groups.all():
return False
return True
# read-only user filter class for ModelAdmin
class ReadOnlyAdmin(admin.ModelAdmin):
def __init__(self, *args, **kwargs):
# keep initial readonly_fields defined in subclass
self._init_readonly_fields = self.readonly_fields
# keep also inline readonly_fields
for inline in self.inlines:
inline._init_readonly_fields = inline.readonly_fields
super().__init__(*args,**kwargs)
# customize change_view to disable edition to readonly_users
def change_view( self, request, object_id, form_url='', extra_context=None ):
context = extra_context or {}
# find whether it is readonly or not
if request.user.is_readonly():
# put all fields in readonly_field list
self.readonly_fields = [ field.name for field in self.model._meta.get_fields() if not field.auto_created ]
# readonly mode fer all inlines
for inline in self.inlines:
inline.readonly_fields = [field.name for field in inline.model._meta.get_fields() if not field.auto_created]
# remove edition buttons
self.save_on_top = False
context['show_save'] = False
context['show_save_and_continue'] = False
else:
# if not readonly user, reset initial readonly_fields
self.readonly_fields = self._init_readonly_fields
# same for inlines
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):
# disable saving model for readonly users
# just in case we have a malicious user...
if request.user.is_readonly():
# si és usuari readonly no guardem canvis
return False
# if not readonly user, save model
return super().save_model( request, obj, form, change )
class ContactAdmin(ReadOnlyAdmin):
list_display = ("name","email","whatever")
readonly_fields = ("updated","created")
inlines = ( PhoneInline, ... )
pipenv install django-admin-view-permission
6666
has_view_permission
在 Django 2.1 中终于得到了实现。另请参见下面的 https://dev59.com/emsy5IYBdhLWcg3w3hyI#51641149。 - djvg