Django自定义User模型恢复username字段,如何设置默认值为email?
解决Django自定义User模型恢复username字段并设置默认值的问题
步骤1:修改模型文件
移除User类中的username = None,保存models.py:
from django.contrib.auth.models import AbstractUser from django.db import models from django.utils.translation import gettext_lazy as _ class User(AbstractUser): # 移除原有的 username = None email = models.EmailField(_("Email address"), unique=True) USERNAME_FIELD = "email"
步骤2:生成迁移文件并退出
执行命令生成迁移文件:
python manage.py makemigrations
当系统提示选择修复方式时,选择选项2(退出并手动定义默认值)。
步骤3:手动修改迁移文件
找到刚生成的迁移文件(路径格式:[你的APP名]/migrations/000x_auto_xxxxxx_xxxx.py),替换内容如下:
from django.db import migrations, models from django.contrib.auth import get_user_model from django.contrib.auth.validators import UnicodeUsernameValidator # 填充现有用户的username为对应email def populate_username_from_email(apps, schema_editor): User = apps.get_model('[你的APP名]', 'User') # 替换为实际APP名称 for user in User.objects.all(): if not user.username: user.username = user.email user.save(update_fields=['username']) class Migration(migrations.Migration): dependencies = [ ('[你的APP名]', '[上一个迁移文件的名称]'), # 保留原依赖,比如0002_user_email_unique ] operations = [ # 1. 先添加允许空值的username字段(避免迁移报错) migrations.AddField( model_name='user', name='username', field=models.CharField( _("username"), max_length=150, unique=True, null=True, help_text=_( "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." ), validators=[UnicodeUsernameValidator()], error_messages={ "unique": _("A user with that username already exists."), }, ), ), # 2. 批量填充现有用户的username migrations.RunPython(populate_username_from_email), # 3. 修改字段为非空,恢复AbstractUser原定义 migrations.AlterField( model_name='user', name='username', field=models.CharField( _("username"), max_length=150, unique=True, null=False, help_text=_( "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." ), validators=[UnicodeUsernameValidator()], error_messages={ "unique": _("A user with that username already exists."), }, ), ), ]
注意:替换代码中的
[你的APP名]和[上一个迁移文件的名称]为实际内容。
步骤4:设置新用户自动用email填充username
因为无法直接重写AbstractUser的username字段添加默认值,用信号处理新用户创建逻辑:
- 在APP目录下创建
signals.py文件:
from django.db.models.signals import post_save from django.dispatch import receiver from django.contrib.auth import get_user_model User = get_user_model() @receiver(post_save, sender=User) def auto_set_username(sender, instance, created, **kwargs): if created and not instance.username: instance.username = instance.email instance.save(update_fields=['username'])
- 修改APP目录下的
apps.py,注册信号:
from django.apps import AppConfig class [你的APP名]Config(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = '[你的APP名]' def ready(self): import [你的APP名].signals # 导入信号模块
步骤5:执行迁移
运行命令完成数据库迁移:
python manage.py migrate
内容的提问来源于stack exchange,提问作者Cool Breeze
相关产品推荐
相关产品推荐

