You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:11:54