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

DRF创建CustomUser报username唯一约束失败错误求助

解决DRF中POST请求触发username唯一约束的IntegrityError

问题根因

你遇到的UNIQUE constraint failed: aao_app_customuser.username错误,核心原因是:

  • 你的CustomUser继承自Django的AbstractUser,父类自带的username字段默认开启唯一约束(unique=True)
  • 你的UserSerializer未将username纳入序列化字段,也没有为该字段提供自动生成逻辑或默认值
  • 第一次POST请求时,数据库中username被存入空字符串(或重复值),第二次请求再存入相同值时,触发唯一约束报错

具体解决方案

方案1:要求前端传入唯一username

修改serializers.py,将username添加到序列化字段中,让DRF自动验证唯一性:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ['id','username','email','password','first_name','last_name']

此后若前端传入重复的username,接口会直接返回400错误,避免触发数据库异常。

方案2:改用email作为用户唯一标识

如果想使用email替代username作为用户标识,修改models.py:

class CustomUser(AbstractUser):
    name = models.CharField(max_length=30)
    email = models.EmailField(default="no email", unique=True)  # 开启email唯一约束
    first_name = models.CharField(max_length=25, default='No name')
    last_name = models.CharField(max_length=25, default='No surname')
    password = models.CharField(max_length=25, default="no password")

    # 设置email为用户唯一标识字段
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []  # 无需额外必填字段

    def __str__(self):
        return self.name

此方式下,创建用户时会以email作为唯一验证依据,不再依赖username字段。

方案3:自动生成唯一username

如果不想依赖前端传入,可在序列化器中自动生成唯一username,比如随机字符串:

import random
import string

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ['id','email','password','first_name','last_name']

    def create(self, validated_data):
        # 生成8位随机唯一username
        while True:
            username = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
            if not CustomUser.objects.filter(username=username).exists():
                break
        validated_data['username'] = username
        
        # 创建用户(建议加密密码,当前代码为明文存储,存在安全风险)
        user = CustomUser.objects.create(**validated_data)
        # 若要加密密码,替换为以下两行:
        # user = CustomUser(**validated_data)
        # user.set_password(validated_data['password'])
        # user.save()
        
        return user

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:36:00