Django创建超级用户时NOT NULL constraint failed错误排查与解决
错误原因与解决方法
错误原因
自定义用户模型的循环关联问题
你的UserRegister是指定的自定义用户模型(通过AUTH_USER_MODEL配置),但模型中冗余添加了user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, on_delete=models.CASCADE)字段,导致用户表自我关联。且该字段仅设置了blank=True(仅作用于表单验证),数据库层面仍为非空约束,创建超级用户时未给该字段赋值,触发NOT NULL约束错误。用户管理器参数顺序错误
create_superuser方法调用create_user时,参数顺序与create_user定义的email, username, password不符,传入的是username, email, password,导致参数错位,超级用户创建时关键字段赋值异常。视图逻辑错误
创建账号的视图中,userRegister.user = request.user(id=pk)存在双重问题:- 创建新账号时用户未登录,
request.user是匿名用户,无法通过id=pk获取有效用户; - 语法错误,即使已登录,正确获取用户的方式也不是
request.user(id=pk),且逻辑上创建新用户无需关联其他用户。
- 创建新账号时用户未登录,
解决方法
1. 修正自定义用户模型
删除冗余的自我关联字段,自定义用户模型本身就是用户核心表:
class UserRegister(AbstractBaseUser, PermissionsMixin): # 移除该行:user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, on_delete=models.CASCADE) username = models.CharField(_("Användarnamn"), max_length=100, null=True, unique=True) age = models.IntegerField() email = models.EmailField(unique=True, null=False) country = models.CharField(max_length=50) county = models.CharField(max_length=50) city = models.CharField(max_length=50) profile_picture = models.ImageField(null=True, default="avatar.svg") is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=False) date_joined = models.DateTimeField(default=timezone.now) USERNAME_FIELD = 'username' REQUIRED_FIELDS = ["email"] objects = UserRegisterManager() def __str__(self): return self.username
2. 修正用户管理器参数顺序
调整create_superuser中调用create_user的参数顺序,与定义一致:
def create_superuser(self, email, username, password, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) extra_fields.setdefault('is_active', True) if extra_fields.get('is_staff') is not True: raise ValueError(_('Superanvändare måste ha is_staff=True.')) if extra_fields.get('is_superuser') is not True: raise ValueError(_('Superanvändare måste ha is_superuser=True.')) # 修正参数顺序:email在前,username在后 return self.create_user(email, username, password, **extra_fields)
3. 修正创建账号的视图逻辑
移除错误的关联代码,同时保留表单错误信息:
page = "create-account" form = UserRegisterForm() if request.method == "POST": form = UserRegisterForm(request.POST) if form.is_valid(): userRegister = form.save(commit=False) # 移除该行:userRegister.user = request.user(id=pk) userRegister.save() #login(request, userRegister) return redirect("generalpage:home-page") # 无需重新实例化form,保留原form即可显示错误信息 context = {"form": form, "page": page} return render(request, "generalpage/create_account.html", context)
4. 重新执行数据库迁移
修改模型结构后,更新数据库:
python manage.py makemigrations python manage.py migrate
开发环境可先清空旧数据避免冲突:
python manage.py flush
5. 重新创建超级用户
现在可正常执行创建命令:
python manage.py createsuperuser
内容的提问来源于stack exchange,提问作者AJJ
相关产品推荐
相关产品推荐

