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

Django切换AbstractUser:auth_user迁移及api_user表不存在问题解决

解决方案:自定义AbstractUser后"no such table: api_user"错误修复及数据迁移

1. 核心配置:指定自定义用户模型

首先必须在项目settings.py中添加配置,告诉Django使用你的自定义User模型:

AUTH_USER_MODEL = 'api.User'  # 替换为你的app名称和模型类名

这一步是关键,缺失会导致Django仍默认使用auth_user表,但你的代码已经定义了新模型,从而引发表不存在的错误。

2. 修复models.py冗余字段问题

你的自定义User继承了AbstractUser,而AbstractUser已经内置了username、email、password等字段,重复定义会引发迁移冲突。修改后的models.py如下:

from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

3. 迁移数据并创建新表(保留原auth_user数据)

由于已有auth_user表,直接执行常规迁移会出错,需按以下步骤操作:

步骤1:生成空迁移文件

  • 删除你的app(如api)的migrations目录下,除__init__.py外的所有迁移文件
  • 运行命令生成初始空迁移:
python manage.py makemigrations api --empty

步骤2:编辑空迁移文件,添加数据迁移逻辑

打开生成的空迁移文件(如0001_initial.py),替换内容如下:

from django.db import migrations, models
from django.contrib.auth import get_user_model

def migrate_auth_user_to_custom_user(apps, schema_editor):
    AuthUser = apps.get_model('auth', 'User')
    CustomUser = get_user_model()
    
    # 批量迁移auth_user数据到自定义User表
    for auth_user in AuthUser.objects.all():
        CustomUser.objects.create(
            id=auth_user.id,
            username=auth_user.username,
            email=auth_user.email,
            password=auth_user.password,
            first_name=auth_user.first_name,
            last_name=auth_user.last_name,
            is_staff=auth_user.is_staff,
            is_active=auth_user.is_active,
            is_superuser=auth_user.is_superuser,
            last_login=auth_user.last_login,
            date_joined=auth_user.date_joined
        )

class Migration(migrations.Migration):
    dependencies = [
        ('auth', '0012_alter_user_first_name_max_length'),  # 保持与你现有auth迁移版本一致
    ]

    operations = [
        # 创建自定义User表结构
        migrations.CreateModel(
            name='User',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('password', models.CharField(max_length=128, verbose_name='password')),
                ('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')),
                ('username', models.CharField(max_length=150, unique=True, verbose_name='username')),
                ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
                ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
                ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
                ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
                ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
                ('date_joined', models.DateTimeField(auto_now_add=True, verbose_name='date joined')),
                ('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={
                'verbose_name': 'user',
                'verbose_name_plural': 'users',
                'abstract': False,
            },
        ),
        # 执行数据迁移
        migrations.RunPython(migrate_auth_user_to_custom_user),
    ]

步骤3:执行迁移

运行命令完成表创建和数据迁移:

python manage.py migrate

4. 更新Admin配置(可选)

如果Admin页面仍有异常,在你的app的admin.py中注册自定义User:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

5. 验证

重启Django服务后登录Admin页面,错误应消失,且原auth_user的数据已迁移至新表api_user中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:20:35