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里已经配置了自定义用户模型:
这一步非常关键,如果没配置,Django还是会用默认的User模型,导致各种奇怪的问题。AUTH_USER_MODEL = 'users.User' - 表单方面,你的
RegisterForm继承UserCreationForm并指定了model = User,这部分是正确的,不需要修改,因为表单会自动适配自定义模型的字段。
按照这些步骤操作后,应该就能解决注册时的唯一约束错误了。
内容的提问来源于stack exchange,提问作者user9152964
相关产品推荐
相关产品推荐

