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

Django更换自定义用户模型后执行迁移报错求助

问题解答

核心结论

Django并非绝对禁止修改已迁移的自定义用户模型名称,但同时保留两个继承了权限系统的用户模型才是引发报错的根本原因——你当前项目里存在userAccount.UserModel和user.UserAccountModel两个用户模型,它们都继承了PermissionsMixin,导致反向关联冲突。

错误原因分析

两个用户模型都继承了PermissionsMixin,这个混入类会自动添加groups和user_permissions两个多对多字段。这两个字段默认的反向关联名称都是user_set,Django处理模型时无法区分Group和Permission对这两个用户模型的反向访问器,因此触发fields.E304冲突错误。

解决方案

方案1:彻底替换旧用户模型(推荐)

这是最规范的做法,避免后续维护混乱:

  • 完全移除旧的userAccount.UserModel:删除该模型代码,或注释掉整个模型类
  • 在项目根目录的settings.py中更新用户模型配置:
    AUTH_USER_MODEL = 'user.UserAccountModel'
    
  • 清理旧迁移记录:
    1. 删除userAccount应用下的migrations文件夹(保留其中的__init__.py)
    2. 清空数据库中django_migrations表内所有属于userAccount应用的记录
  • 重新生成并执行迁移:
    python manage.py makemigrations
    python manage.py migrate
    

方案2:临时添加唯一反向关联名称(不推荐)

如果仅临时测试需要保留两个用户模型,可以手动重写groups和user_permissions字段,指定唯一的related_name:
在user.UserAccountModel中添加以下代码:

from django.contrib.auth.models import Group, Permission

class UserAccountModel(AbstractBaseUser,PermissionsMixin):
    # 原有字段...
    
    # 重写groups字段,指定唯一related_name
    groups = models.ManyToManyField(
        Group,
        verbose_name=_('groups'),
        blank=True,
        related_name='user_account_groups',
        related_query_name='user_account',
    )
    # 重写user_permissions字段,指定唯一related_name
    user_permissions = models.ManyToManyField(
        Permission,
        verbose_name=_('user permissions'),
        blank=True,
        related_name='user_account_permissions',
        related_query_name='user_account',
    )
    
    # 原有方法...

但这种方式会导致项目存在两个独立用户体系,后续业务逻辑会极度复杂,不建议在生产环境使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:50:37