Django ORM插入数据时设了默认值的is_routed字段报不能为空错误
问题原因
Django ORM不会自动读取数据库侧配置的字段默认值,默认逻辑是:如果模型字段未配置default参数,创建实例时未传入该字段值,ORM会在生成的INSERT语句中显式将该字段值设为NULL。
你当前的场景中存在两个触发报错的条件:
UserOrder模型的is_routed字段未设置null=True,Django默认该字段非空,但你创建实例时没有传值,ORM直接生成了is_routed = NULL的插入逻辑- 插入语句中显式指定了
is_routed为NULL,即使数据库侧配置了默认值,MySQL也不会触发默认值逻辑,只会直接命中非空约束抛出报错
另外你设置了managed = False,Django不会同步模型和数据库的字段配置,所以即使数据库有默认值,Django侧也感知不到。
解决方案
你可以选择以下任意一种方式解决:
- 方案1:对齐数据库默认值,给模型字段补充
default配置
直接修改models.py中对应字段的定义,和数据库侧的默认值保持一致即可,其他有数据库默认值的字段也可以同步修改:
该方案适配性最好,后续创建实例时无需额外传参,Django会自动填充默认值生成插入语句。is_routed = models.IntegerField(default=0) - 方案2:使用Django 3.2+版本提供的
db_default参数声明数据库侧默认值
如果你不想在Django侧重复配置默认值,可以用db_default告知Django该字段已有数据库层面的默认值,插入时不会自动补NULL:from django.db.models import Value # 字段定义修改为 is_routed = models.IntegerField(db_default=Value(0)) - 方案3:保存实例时指定
update_fields参数,排除未传值的字段
如果你不想修改模型定义,可以在调用save()方法时指定本次插入需要更新的字段列表,未被包含的字段不会出现在INSERT语句中,数据库会自动填充默认值:placeorder_userorder.save(update_fields=[ 'order_status', 'listing_id', 'actual_cost', 'order_total', 'total_without_dc', 'discount', 'gst', 'auto_invoice_index' ])
内容的提问来源于stack exchange,提问作者Ajay Chaurasia
相关产品推荐
相关产品推荐

