如何修改Django-Admin详情视图?按用户/状态显示对应字段
看起来你之前的思路方向是对的,但写法上有几个问题导致没生效——首先show_relevant这个方法不会被Django Admin自动调用,而且你在方法里直接定义fieldsets也不是正确的动态修改方式。下面我给你两种场景的完整实现,分别是按用户类型和按条目Status字段来控制详情页的字段、按钮显示:
1. 根据用户类型动态控制字段(比如超级用户 vs 普通用户)
要实现这个需求,你需要重写ModelAdmin的get_fieldsets方法——这是Django Admin专门用来动态生成详情页字段分组的钩子,它能接收当前请求request和待编辑的对象obj两个参数,完美适配按用户权限控制字段的场景。
完整示例代码:
class JournalEntriesAdmin(admin.ModelAdmin): list_display = ('EngagementCode', 'EngagementManager', 'EngagementIncharge') list_filter = ('published', 'EngagementCode') search_fields = ('EngagementCode', 'EngagementManager', 'EngagementIncharge') def get_fieldsets(self, request, obj=None): # 定义所有用户都能看到的基础字段组 base_fieldsets = ( (None, { 'fields': (('EngagementCode', 'EngagementManager'),) }), ) # 给超级用户额外添加可折叠的详情字段组 if request.user.is_superuser: base_fieldsets += ( ('More details', { 'classes': ('collapse',), 'fields': ('published',) }), ) return base_fieldsets # 可选:如果需要控制字段是否只读,重写这个方法 def get_readonly_fields(self, request, obj=None): if not request.user.is_superuser: # 普通用户无法修改EngagementCode return ('EngagementCode',) # 超级用户使用默认的只读字段设置 return super().get_readonly_fields(request, obj)
2. 根据条目Status字段动态控制字段
如果要根据当前条目的Status值(假设你的模型里有status字段,比如draft/published状态)来显示不同字段,同样在get_fieldsets里判断obj的状态即可。注意要先判断obj是否为None(新增条目时没有对象,避免报错)。
示例代码:
class JournalEntriesAdmin(admin.ModelAdmin): # 保留原有属性... list_display = ('EngagementCode', 'EngagementManager', 'EngagementIncharge', 'status') list_filter = ('published', 'EngagementCode', 'status') search_fields = ('EngagementCode', 'EngagementManager', 'EngagementIncharge') def get_fieldsets(self, request, obj=None): # 新增条目时,显示所有可编辑字段 if obj is None: return ( (None, { 'fields': (('EngagementCode', 'EngagementManager'), 'published', 'status') }), ) # 根据已有条目的status字段判断显示内容 if obj.status == 'published': # 已发布的条目只展示不可修改的核心字段 return ( (None, { 'fields': (('EngagementCode', 'EngagementManager'),) }), ('Published Info', { 'fields': ('published', 'status') }), ) else: # 草稿状态的条目可以编辑更多字段 return ( (None, { 'fields': (('EngagementCode', 'EngagementManager'),) }), ('Edit Details', { 'classes': ('collapse',), 'fields': ('published', 'status', 'some_other_editable_field') }), )
3. 控制详情页的按钮(删除/保存等)
如果要根据用户类型或条目状态控制按钮显示,最简便的方式是重写Admin的权限判断方法:
- 控制删除权限:
def has_delete_permission(self, request, obj=None): # 只有超级用户,或者草稿状态的条目允许删除 if request.user.is_superuser: return True if obj and obj.status == 'draft': return True return False
- 控制修改权限:
def has_change_permission(self, request, obj=None): # 已发布的条目,普通用户无法修改 if obj and obj.status == 'published' and not request.user.is_superuser: return False return super().has_change_permission(request, obj)
Django Admin会自动根据这些权限方法的返回值,隐藏或显示对应的按钮,无需手动修改模板。
内容的提问来源于stack exchange,提问作者webmourek
相关产品推荐
相关产品推荐

