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

Django自定义用户模型注册报错:UNIQUE constraint failed: users_user.username

解决Django自定义用户模型注册时的UNIQUE约束错误

看起来你遇到的问题根源在于AbstractUser自带的username字段——虽然你把USERNAME_FIELD设为了email,但AbstractUser默认的username字段仍然保留着unique=True的约束。当你提交注册表单时,因为表单里没有提供username值,Django会自动把它设为空字符串,第二次注册时就会因为重复的空字符串触发唯一约束错误。

下面是具体的解决步骤:

1. 修改自定义User模型,覆盖username字段

在你的models.py里,重新定义username字段,移除它的唯一约束:

class User(AbstractUser):
    # 覆盖AbstractUser的username字段,去掉唯一约束
    username = models.CharField(max_length=150, blank=True, null=True, unique=False)
    email = models.EmailField(
        verbose_name='Epostadresse',
        max_length=255,
        unique=True,
    )
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    veri_mail = models.BooleanField(default=False)

    objects = UserManager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

这样一来,username字段不再要求唯一,空字符串重复也不会触发错误了。如果你完全不需要username字段,甚至可以把它设置为db_column=None来彻底移除,但覆盖字段并取消唯一约束是更稳妥的方式,避免和AbstractUser的其他逻辑冲突。

2. 确保UserManager正确适配自定义模型

虽然你已经声明了objects = UserManager(),要确认你的UserManager是正确继承并配置的。如果还没定义UserManager,需要补充:

from django.contrib.auth.models import UserManager

class UserManager(UserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('The Email field must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_admin', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self.create_user(email, password, **extra_fields)

这个Manager会确保创建用户时只使用email作为标识,不会依赖username。

3. 重新生成迁移并同步数据库

因为你修改了模型字段的约束,需要重新生成迁移文件并执行:

# 删除原来的迁移文件(users应用下的migrations文件夹里除了__init__.py都删掉)
rm -rf users/migrations/*.py
# 生成新的迁移
python manage.py makemigrations
# 执行迁移
python manage.py migrate

注意:如果是生产环境,不要直接删除迁移文件,应该生成新的迁移来修改字段约束;开发环境这样操作没问题。

额外检查点

  • 确认你的settings.py里已经配置了自定义用户模型:
    AUTH_USER_MODEL = 'users.User'
    
    这一步非常关键,如果没配置,Django还是会用默认的User模型,导致各种奇怪的问题。
  • 表单方面,你的RegisterForm继承UserCreationForm并指定了model = User,这部分是正确的,不需要修改,因为表单会自动适配自定义模型的字段。

按照这些步骤操作后,应该就能解决注册时的唯一约束错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:14:42