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

如何在Django的admin.py中校验用户是否属于指定默认用户组

Django Admin 按用户组动态返回fieldsets的正确实现方案

原有写法错误原因

  • 写法a:request.user.groups 是Django ORM的关系管理器对象,不是可调用方法,且直接实例化Group对象作为查询条件的写法不符合ORM查询规范,因此触发NoneType不可调用报错
  • 写法b:直接取下标[0]的前提是用户必须属于至少一个用户组,当用户未加入任何组时groups.all()返回空列表,触发索引越界报错
  • 写法c:原生Django环境下该写法是合法的,出现unhashable type: 'dict'报错大概率是你的项目中自定义了User模型的groups字段(类型为dict)、或者存在第三方组件/自定义逻辑覆盖了默认的Group关联管理器,替换为遍历取值的判断方式即可规避该问题

正确实现代码

你可以在对应的ModelAdmin类中重写get_fieldsets方法,先提取当前用户所有所属组的名称,再判断目标组是否存在,根据判断结果返回不同的字段配置,示例如下:

from django.contrib import admin
from .models import News # 替换为你自己的业务模型

class NewsAdmin(admin.ModelAdmin):
    # 定义外包组用户可见的受限字段配置
    restricted_fieldsets = (
        (None, {
            'fields': ('title', 'content', 'publish_time') # 替换为你要对外包组开放的字段
        }),
    )
    # 定义内部用户可见的全量字段配置
    full_fieldsets = (
        (None, {
            'fields': ('title', 'content', 'publish_time', 'status', 'author', 'is_top')
        }),
        ('高级配置', {
            'classes': ('collapse',),
            'fields': ('slug', 'seo_keywords', 'seo_description')
        }),
    )

    def get_fieldsets(self, request, obj=None):
        # 提取当前用户所有所属组的名称,转成集合后查询效率更高
        user_group_names = set(request.user.groups.values_list('name', flat=True))
        # 判断是否属于外包组,返回对应字段配置
        if 'OutSource' in user_group_names:
            return self.restricted_fieldsets
        return self.full_fieldsets

# 注册模型到Admin
admin.site.register(News, NewsAdmin)

异常排查提示

如果仍出现unhashable type: 'dict'报错,请优先排查两个点:

  1. 你的项目中是否对默认User模型做了自定义修改,新增了类型为dict、名为groups的字段,覆盖了默认的用户组关联关系
  2. 是否安装了第三方权限相关的应用,修改了User模型的groups属性默认实现

内容的提问来源于stack exchange,提问作者Abduhamidov Jordan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:27:00