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

Django自定义用户模型request.user.groups返回auth.Group.None排查

问题原因

数据库层面用户和组的关联已经正常写入,说明关联中间表数据没问题,request.user.groups返回auth.Group.None本质是模型层的多对多关系映射异常,通常是后期追加PermissionsMixin继承时迁移不完整、字段冲突导致的。另外注意:直接打印多对多字段返回的是关系管理器对象,本身就会显示为模型名.None格式,需要调用.all()才能拿到实际关联数据,这是Django ORM的正常表现,不是报错。

排查步骤
  • 检查UserProfile模型代码,确认没有手动定义groups、user_permissions同名的字段或属性,避免覆盖PermissionsMixin自带的关系定义。
  • 检查追加PermissionsMixin时生成的迁移文件,确认operations里包含groups、user_permissions两个多对多字段的创建操作,很多时候因为初始模型存在残留结构,makemigrations会漏生成这部分操作。
  • 进入Django shell执行以下代码,验证模型字段是否正常加载:
from 你的应用名.models import UserProfile
# 检查是否存在groups属性
print(hasattr(UserProfile, 'groups'))
# 打印字段配置
print(UserProfile._meta.get_field('groups'))

如果返回False或者报字段不存在错误,说明多对多关系没有正确挂载到模型上。

  • 检查settings.py里的AUTH_USER_MODEL配置是否正确指向你的UserProfile模型,配置错误会导致权限关联关系映射到默认的auth.User模型上,和自定义用户模型脱节。
修复方案
  1. 清理冲突字段:删除UserProfile里手动定义的groups、user_permissions字段,这两个字段默认由PermissionsMixin提供,不需要手动声明。如果存在反向名冲突(启动服务时报related_name冲突错误),可以手动声明两个字段并指定唯一的related_name:
from django.contrib.auth.models import Group, Permission

class UserProfile(AbstractBaseUser, PermissionsMixin):
    # 原有字段保持不变
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']
    first_name = models.CharField(max_length=50, blank=True, null=True)
    middle_name = models.CharField(max_length=50, blank=True, null=True)
    last_name = models.CharField(max_length=50, blank=True, null=True)

    # 仅当出现反向名冲突时追加以下字段声明,无冲突可省略
    groups = models.ManyToManyField(
        Group,
        verbose_name='用户组',
        blank=True,
        related_name="user_profiles",
        related_query_name="user_profile",
    )
    user_permissions = models.ManyToManyField(
        Permission,
        verbose_name='用户权限',
        blank=True,
        related_name="user_profiles",
        related_query_name="user_profile",
    )
  1. 补全迁移:如果之前的迁移漏了两个多对多字段的创建,执行命令重新生成迁移:
python manage.py makemigrations 你的应用名

如果makemigrations没有检测到变更,可以手动在最新的迁移文件里追加两个多对多字段的AddField操作,注意保持迁移依赖正确。
3. 执行迁移同步数据库结构:

python manage.py migrate
  1. 验证:重启服务后修改测试代码,调用.all()方法获取实际关联数据:
for group in Group.objects.all():
    print(group, group.id)    
request.user.groups.add(Group.objects.get(id=2))
print(Group.objects.get(user=request.user))
print(request.user.groups.all())  # 必须加.all()才能拿到实际查询结果

正常情况下最后一行会输出<QuerySet [<Group: business_customers>]>,问题修复完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:01:53