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

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字段添加默认值,用信号处理新用户创建逻辑:

  1. 在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'])
  1. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:45:31