重写Django ModelForm save方法删除旧文件时新图片未保存到实例问题
问题原因
Django 的 FileField/ImageFieldFile 实例调用 delete() 方法时默认携带 save=True 参数,会执行两个操作:
- 删除磁盘上对应的存储文件
- 将关联的模型实例对应字段设为
None,并自动调用一次模型的save()方法把空值写入数据库
你的代码执行流程恰好触发了这个逻辑:
- 先执行
super().save(commit=True):此时新上传的图片路径已经写入数据库,新文件也已经存入磁盘 - 随后调用旧文件的
old_value.delete():这一步会把当前模型实例的图片字段置为None,再自动执行一次保存操作,直接把你之前写入的新图片路径覆盖为空值
这完全匹配你遇到的现象:首次上传没有旧文件不会触发 delete(),所以一切正常;更新时旧文件被删除,新文件存入了磁盘,但数据库字段最终被覆盖为空。
修复方案
只需要在调用 delete() 时显式传入 save=False,阻止它自动修改模型字段和触发额外保存即可:
if old_value and (isinstance(old_value, FileField) or isinstance(old_value, ImageFieldFile)): # 只删除旧文件,不修改模型实例字段,也不触发额外保存 old_value.delete(save=False)
内容的提问来源于stack exchange,提问作者muremwa
相关产品推荐
相关产品推荐

