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

Django自定义NewUser用户模型执行数据库迁移报ValueError咨询

Django自定义用户模型迁移懒引用报错修复方案

报错信息

ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'user.newuser', but app 'user' doesn't provide model 'newuser'.
The field user.UserInfo.user was declared with a lazy reference to 'user.newuser', but app 'user' doesn't provide model 'newuser'.

问题根因

报错是迁移依赖链断裂导致:你之前的0015_delete_newuser迁移已经将NewUser模型标记为删除状态,但Django内置的admin.LogEntry模型、你自建的UserInfo模型仍然保留着对user.NewUser的外键懒引用,新建NewUser的迁移没有同步更新这些外键关联,就会触发找不到模型的错误。另外你的现有代码存在3个会引发后续功能异常的bug,需要先修复。

修复步骤

1. 先修复模型代码bug

  • 修复CustomAccountManager的create_superuser方法:原方法存在参数顺序错位、调用create_user无返回值两个问题,修正后代码如下:
def create_superuser(self, email, first_name, last_name, phone_number, password, **other_fields):
    other_fields.setdefault('is_staff', True)
    other_fields.setdefault('is_superuser', True)
    other_fields.setdefault('is_active', True)

    if other_fields.get('is_staff') is not True:
        raise ValueError(_('Superuser must be assigned to is_staff=True'))
    if other_fields.get('is_active') is not True:
        raise ValueError(_('Superuser must be assigned to is_active=True'))
    if other_fields.get('is_superuser') is not True:
        raise ValueError(_('Superuser must be assigned to is_superuser=True'))
    # 修正参数顺序和create_user入参对齐,添加return返回创建的用户实例
    return self.create_user(first_name, last_name, phone_number, email, password, **other_fields)
  • 删除NewUser模型里多余的字段:AbstractBaseUser已经内置了password字段,不需要重复定义;confirm_password是表单校验层字段,不应该放在模型层,直接删掉这两个字段的定义即可。

2. 清理断裂的迁移记录(开发环境推荐方案,无残留问题)

  • 删除user应用下migrations文件夹中除__init__.py之外的所有文件
  • 如果home、pages、reservation等其他应用存在关联用户模型的外键,同步删除这些应用migrations文件夹中除__init__.py之外的所有文件
  • 删除本地数据库文件(开发环境默认是db.sqlite3,使用MySQL/PostgreSQL的话直接删除对应库后重建空库即可)

3. 重新生成并执行迁移

按顺序执行以下命令:

# 优先生成用户应用的初始迁移
python manage.py makemigrations user
# 生成其余应用的迁移
python manage.py makemigrations
# 执行全量迁移
python manage.py migrate

迁移执行完成后,再执行python manage.py createsuperuser创建管理员账号即可正常使用。

生产环境替代方案(不删库/不删迁移场景)

如果是生产环境不能清空数据,可以直接修改你当前创建NewUser的迁移文件,在CreateModel操作之后追加两个外键更新操作,同步修正懒引用指向:

operations = [
    migrations.CreateModel(
        # 你原有的NewUser创建逻辑保持不变
        name='NewUser',
        fields=[
            ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
            ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
            ('first_name', models.CharField(blank=True, max_length=200, null=True)),
            ('last_name', models.CharField(blank=True, max_length=200, null=True)),
            ('email', models.EmailField(blank=True, max_length=200, null=True, unique=True)),
            ('phone_number', models.CharField(blank=True, max_length=10, null=True)),
            ('address', models.TextField(blank=True, null=True)),
            ('pin_code', models.CharField(blank=True, max_length=6, null=True)),
            ('region', models.CharField(blank=True, max_length=200, null=True)),
            ('state', models.CharField(blank=True, max_length=100, null=True)),
            ('start_date', models.DateField(default=django.utils.timezone.now)),
            ('is_staff', models.BooleanField(default=False)),
            ('is_active', models.BooleanField(default=False)),
            ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
            ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
        ],
        options={'abstract': False,},
    ),
    # 追加以下两个操作更新关联外键
    migrations.AlterField(
        model_name='logentry',
        name='user',
        field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user'),
    ),
    migrations.AlterField(
        model_name='userinfo',
        name='user',
        field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
    ),
]

修改完成后再执行python manage.py migrate即可正常完成迁移。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:39:43