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
相关产品推荐
相关产品推荐

