Django存储Canvas到模型FileField报错'Canvas' object has no attribute '_committed'
报错原因
Django 模型的File字段在接收数据时,会校验传入对象是否存在_committed属性,以此判断该文件是否已完成持久化相关的标记逻辑。你直接将 ReportLab 的Canvas实例p传给了File字段,而Canvas对象本身没有内置该属性,因此直接触发属性不存在的异常。
另外你代码中调用p.save()只是将PDF内容写入了内存缓冲区,并没有生成Django可以识别的文件类对象,直接传入Canvas实例本身就是错误的用法。
修复步骤
- 首先导入Django内置的
ContentFile类,该类是对字节流的包装,原生适配File字段的校验规则,自带_committed属性 - 将你已经生成的PDF字节流包装为
ContentFile实例,同时指定合法的文件名 - 修正
update_or_create的传参格式,更新字段需要放入defaults参数中,避免被当成查询过滤条件
修复后代码示例
# 头部导入ContentFile from django.core.files.base import ContentFile # 原有PDF生成逻辑保持不变 p.setTitle(f"{patient.first_name} {patient.last_name}'s Report") p.showPage() p.save() pdf_bytes = buffer.getvalue() buffer.close() response.write(pdf_bytes) # 包装字节流为Django可识别的文件对象 pdf_file = ContentFile(pdf_bytes, name=f"{patient.first_name}_{patient.last_name}_report.pdf") # 正确调用update_or_create r = Result.objects.filter(score="12").update_or_create(defaults={"file": pdf_file})
内容的提问来源于stack exchange,提问作者Syed Muhammad Ibrahim
相关产品推荐
相关产品推荐

