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

Django开发POST API报IntegrityError:key_value_id非空约束失败

报错根因

触发django.db.utils.IntegrityError: NOT NULL constraint failed: app_users.key_value_id是三个问题叠加导致的:

  1. 序列化器语法错误:KeySerializer的Meta类中用冒号给model赋值,且绑定的模型名Keys和你实际定义的KeyTable不匹配,序列化逻辑完全没生效。
  2. 模型配置缺漏:Users模型里的vendor_name外键只设了default=None没加null=True,数据库层面该字段默认是非空约束;就算你给key_value加了null=True,如果修改模型后没执行迁移,数据库里的字段约束还是旧的非空配置。
  3. 接口传参逻辑问题:POST创建用户时,如果没传key_value参数,序列化器可能把空值解析为空字符串而非None,ORM写入时找不到对应的关联KeyTable记录,就会触发外键字段的非空约束报错。
修复步骤
  • 修正KeySerializer的语法和模型绑定错误:
class KeySerializer(serializers.ModelSerializer):
    class Meta:
         # 注意Meta类属性赋值用等号,模型名要和你定义的类名完全一致
         model = KeyTable
         fields = ['key_id', 'key_value', 'issue_date', 'expiry_date', 'status', 'license_tenure']
  • 补全Users模型的外键字段配置,给vendor_name加上null=True:
class Users(AbstractBaseUser):
       # 外键设置default=None必须搭配null=True,否则数据库层面不会允许空值
       vendor_name = models.ForeignKey(Vendor, on_delete=models.CASCADE, default=None, null=True)
       key_value = models.ForeignKey(KeyTable, on_delete=models.CASCADE, default=None, null=True)
       username = models.CharField(max_length=100, verbose_name="username", unique=True)
       password = models.CharField(max_length=100)
       hardware_id = models.CharField(max_length=150, null=True)
       created_by = models.DateField(verbose_name="created_by", auto_now_add=True)

       USERNAME_FIELD = "username"
       REQUIRED_FIELDS = ['password', 'hardware_id']

       is_active = models.BooleanField(default=True)
       is_admin = models.BooleanField(default=False)
       is_role_vendor = models.BooleanField(default=False)
       is_role_customer = models.BooleanField(default=True)

       def __str__(self):
             return self.username

       objects = UserManager()
  • 执行数据库迁移,同步表结构约束:
python manage.py makemigrations
python manage.py migrate
  • 调整用户创建相关的序列化器配置:如果创建用户时允许不绑定密钥,给UserSerializer里的key_value、vendor_name字段加上required=False参数,同时做空值转换,确保接口收到空参数时传给ORM的是None,而不是空字符串、0这类会触发外键匹配失败的值。

额外优化建议:你在KeyTable里手动定义的key_id = models.IntegerField(unique=True, auto_created=True)是无效写法,Django会默认给所有模型生成自增主键id字段,手动定义的这个字段不会自动自增,还容易引发主键重复问题,直接删掉该字段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:01:04