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
相关产品推荐
相关产品推荐

