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

Django报Duplicate key唯一约束错误,如何实现匹配id时更新模型创建时间

问题根因分析
  • 海象运算符优先级错误:你写的a:=Defect.objects.get(id_leather=id_file_name) == True实际执行顺序是a := (Defect.objects.get(...) == True),Django模型实例不等于布尔值True,所以a永远是False,代码永远走else分支执行创建逻辑,自然触发唯一键冲突报错
  • get()方法行为不符合预期:Django ORM的get()方法找不到匹配项时会直接抛出DoesNotExist异常,不会返回False,你写的判断逻辑完全不生效
  • auto_now_add字段默认不可编辑:你定义的created字段加了auto_now_add=True参数,默认情况下只有创建对象时会自动赋值,后续普通修改/更新操作会直接忽略该字段的赋值
修复方案

方案1:使用Django内置原子方法update_or_create(推荐)

这个方法天生适配「存在则更新、不存在则创建」的场景,是数据库层面的原子操作,不会出现并发导致的唯一键冲突问题。另外建议使用Django自带的时区工具代替原生datetime避免时区问题:

from django.utils import timezone

Defect.objects.update_or_create(
    id_leather=id_file_name,
    defaults={
        "created": timezone.now(),
        "path": path_file_save
    }
)

如果不需要每次都覆盖path字段,只需要更新created的话,defaults参数里只保留created配置即可。

方案2:修正原有逻辑的写法

如果你要保留原来的if-else写法,需要先捕获DoesNotExist异常,同时修正赋值逻辑:

from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist

try:
    defect_obj = Defect.objects.get(id_leather=id_file_name)
    defect_obj.created = timezone.now()
    defect_obj.save(update_fields=["created"])
except ObjectDoesNotExist:
    Defect.objects.create(id_leather=id_file_name, path=path_file_save)

可选优化:调整created字段定义

如果你后续需要频繁修改created字段,建议把字段的auto_now_add参数去掉,改为设置默认值,后续修改不需要特殊处理:

from django.utils import timezone

class Defect(models.Model):
    created = models.DateTimeField(default=timezone.now)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:00:01