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

Django创建超级用户触发IntegrityError问题求助

Django自定义邮箱登录用户模型创建超级用户报IntegrityError的解决办法

问题原因

你遇到的IntegrityError本质是自定义用户模型未正确处理username字段的唯一约束:

  • Django默认AbstractUser中的username是唯一且非空字段,当你改成用邮箱登录时,若仅设置username=null=True但未取消其unique=True属性,数据库会保留username的唯一约束。
  • PostgreSQL中空值被视为唯一值,若数据库中已存在一条username为空的用户记录,再次创建超级用户时,新用户的username默认会被设为空,直接触发唯一约束冲突。

解决步骤

方案1:基于AbstractUser改造(保留username字段但取消唯一约束)

适合不想完全重构用户模型的场景:

  1. 修改accounts/models.py中的CustomUser类:
    from django.contrib.auth.models import AbstractUser
    from django.db import models
    
    class CustomUser(AbstractUser):
        # 取消username的唯一约束,允许为空
        username = models.CharField(max_length=150, blank=True, null=True, unique=False)
        # 设置邮箱为唯一标识
        email = models.EmailField(unique=True)
        # 指定用邮箱作为登录用户名
        USERNAME_FIELD = 'email'
        # 超级用户创建时无需额外必填字段(邮箱已作为USERNAME_FIELD)
        REQUIRED_FIELDS = []
    
  2. 执行数据库迁移:
    py manage.py makemigrations
    py manage.py migrate
    
  3. 清理现有冲突数据(如果数据库已有空username记录):
    进入Django Shell执行:
    py manage.py shell
    from accounts.models import CustomUser
    # 删除所有username为空的用户
    CustomUser.objects.filter(username__isnull=True).delete()
    
  4. 重新创建超级用户:
    py manage.py createsuperuser
    

方案2:基于AbstractBaseUser重构(完全移除username字段)

适合彻底用邮箱作为用户唯一标识的场景:

  1. 修改accounts/models.py,自定义用户管理器和模型:
    from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
    from django.db import models
    
    class CustomUserManager(BaseUserManager):
        def create_user(self, email, password=None, **extra_fields):
            if not email:
                raise ValueError('必须填写邮箱地址')
            # 标准化邮箱格式
            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):
            # 超级用户默认开启staff和superuser权限
            extra_fields.setdefault('is_staff', True)
            extra_fields.setdefault('is_superuser', True)
            return self.create_user(email, password, **extra_fields)
    
    class CustomUser(AbstractBaseUser, PermissionsMixin):
        email = models.EmailField(unique=True, verbose_name='邮箱')
        is_active = models.BooleanField(default=True, verbose_name='是否激活')
        is_staff = models.BooleanField(default=False, verbose_name='是否为后台管理员')
        date_joined = models.DateTimeField(auto_now_add=True, verbose_name='注册时间')
    
        # 绑定自定义管理器
        objects = CustomUserManager()
    
        # 指定邮箱为登录字段
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = []
    
  2. 执行迁移并创建超级用户:
    py manage.py makemigrations
    py manage.py migrate
    py manage.py createsuperuser
    

配套代码调整

表单(forms.py)

确保用户相关表单使用自定义模型:

from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ('email',)

class CustomUserChangeForm(UserChangeForm):
    class Meta:
        model = CustomUser
        fields = ('email', 'is_staff', 'is_active')

登录视图(views.py)

自定义登录表单,让用户输入邮箱登录:

from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login
from django.shortcuts import render, redirect

class EmailLoginForm(AuthenticationForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 把表单中的"用户名"标签改为"邮箱"
        self.fields['username'].label = '邮箱'

def user_login(request):
    if request.method == 'POST':
        form = EmailLoginForm(request, data=request.POST)
        if form.is_valid():
            login(request, form.get_user())
            return redirect('home') # 替换为你的首页路由
    else:
        form = EmailLoginForm()
    return render(request, 'accounts/login.html', {'form': form})

关键配置检查

确保settings.py中已指定自定义用户模型:

AUTH_USER_MODEL = 'accounts.CustomUser'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 00:47:28