Django使用.update()更新PostgreSQL表字段不生效及报错如何解决
问题原因分析
- 关于
AttributeError: 'int' object has no attribute 'save'报错:
Django的ORM中QuerySet.update()方法的返回值是受本次更新影响的行数,为整数类型,本身没有save方法。你追加save()调用时,update已经执行完成并将数据写入数据库,所以数据库值更新成功,但后续对整数调用save才抛出异常。 - 前两种写法未生效的常见原因:
- 条件判断未触发:
total_payments_for_invoice.all().count() == 1的判断结果为False,更新逻辑根本没有执行,建议在if块内加打印或日志确认逻辑是否正常进入。 - 模型逻辑拦截:如果你的
Invoice模型自定义了save方法,没有调用父类的super().save(),或者绑定了pre_save信号、字段clean方法,会修改你设置的invo_payment_method值,或者直接终止保存流程。 - 事务未提交:如果你的代码开启了手动事务管理,更新后没有执行commit操作,数据不会实际写入数据库。
- 缓存导致的假象:如果你查询更新结果时使用的是之前获取的旧实例,没有调用
refresh_from_db()从数据库拉取最新值,会误以为更新没生效。
- 条件判断未触发:
解决方案
方案1:使用get+save的写法(适合需要触发模型save逻辑、信号的场景)
# 直接调用QuerySet.count()不需要先all(),性能更高 if total_payments_for_invoice.count() == 1: try: invoice_object = Invoice.objects.get(slug=slug) invoice_object.invo_payment_method = request.POST.get('payment_method') # 仅更新指定字段,避免其他字段被意外修改,提升执行效率 invoice_object.save(update_fields=['invo_payment_method']) # 如果要验证更新结果,调用refresh_from_db后再读字段 # invoice_object.refresh_from_db() # print(invoice_object.invo_payment_method) except Invoice.DoesNotExist: # 自行处理发票不存在的异常逻辑,比如记录日志 pass
方案2:使用update写法(适合不需要触发模型save逻辑、性能要求高的场景)
if total_payments_for_invoice.count() == 1: # update本身已经直接执行SQL写入数据库,不需要额外调用save updated_rows = Invoice.objects.filter(slug=slug).update( invo_payment_method=request.POST.get('payment_method') ) # updated_rows为本次更新的行数,正常情况下匹配到目标发票时为1
内容的提问来源于stack exchange,提问作者Jaime Miranda Ramirez
相关产品推荐
相关产品推荐

