调用Invoice.save()时出现‘Invoice matching query does not exist’错误排查
首先得明确:你遇到的Invoice matching query does not exist错误根本不是来自你写的创建保存代码——毕竟你已经测试过,哪怕只创建空的Invoice对象直接保存,都会触发这个错误。问题出在Invoice模型的内部逻辑,或者关联的Django信号(Signal)里,下面一步步拆解:
错误原因
重写了Invoice的
save()方法
如果你的Invoice模型自定义了save()方法,里面大概率有代码在尝试查询某个Invoice实例,但目标实例不存在。比如类似Invoice.objects.get(pk=some_value)的代码,当some_value对应的记录不存在时,就会抛出这个异常。关联的Django信号接收器
项目里的pre_save/post_save这类信号中,可能有针对Invoice模型的处理逻辑,其中包含了查询Invoice的操作,但查询条件对应的记录不存在。比如保存新Invoice时,信号函数里去查询一个特定的旧Invoice,但那个旧记录压根不存在。模型的
clean()验证逻辑
如果Invoice类里写了自定义的clean()方法,或者字段验证逻辑中涉及查询Invoice实例,也可能触发这个错误。
另外注意错误日志里的invoice_settings_create_new_invoice,直接在项目里搜索这个字符串,能快速定位到触发错误的具体函数/方法,节省排查时间。
排查与修复步骤
1. 检查Invoice模型的save()方法
打开你的models.py里的Invoice类,找是否有类似这样的代码:
def save(self, *args, **kwargs): # 这里可能有问题的查询逻辑 target_invoice = Invoice.objects.get(pk=self.related_invoice_id) super().save(*args, **kwargs)
修复方式:把get()改成filter().first(),避免查询不到时抛出异常,再根据业务逻辑处理空值:
target_invoice = Invoice.objects.filter(pk=self.related_invoice_id).first() if target_invoice is None: # 可选:抛出验证错误,或者跳过相关逻辑 raise ValidationError("关联的Invoice不存在")
2. 检查Django信号
搜索项目里的信号代码(通常在signals.py或models.py里),找针对Invoice的接收器:
@receiver(pre_save, sender=Invoice) def handle_invoice_pre_save(sender, instance, **kwargs): # 这里的查询可能出问题 existing_invoice = Invoice.objects.get(name=instance.name)
修复方式:先做存在性检查再查询:
if Invoice.objects.filter(name=instance.name).exists(): existing_invoice = Invoice.objects.get(name=instance.name) # 后续业务逻辑 else: logger.warning(f"未找到名称为{instance.name}的Invoice") # 跳过逻辑或做其他处理
3. 检查模型的clean()方法
查看Invoice类是否有自定义的验证逻辑:
def clean(self): # 这里的查询可能触发异常 Invoice.objects.get(pk=self.some_field) super().clean()
修复逻辑和上面一致,用filter().first()替代get(),并处理空值场景。
内容的提问来源于stack exchange,提问作者Skif

