Django保存处理后图片到数据库报UnboundLocalError如何解决
问题排查与修复方案
核心报错原因
你遇到的UnboundLocalError: local variable 'listing' referenced before assignment报错,本质是代码执行到listing.restoredimage = None这一行时,还没有初始化/查询获取到Listing模型的实例对象,变量listing根本不存在,自然无法给它的属性赋值。
具体修复步骤
- 第一步:先获取/创建
Listing实例
你需要先完成Listing对象的初始化,再对它的属性赋值,参考代码:
# 如果你是新增商品场景,先创建实例,必填字段按你的业务逻辑补全 listing = Listing.objects.create( item="示例商品名", price=99.99, owner=request.user, # 其他你业务里要求的必填字段都要传入 ) # 如果你是修改已有商品场景,先从数据库查询对应实例 # listing = Listing.objects.get(id=待修改商品的id值)
- 第二步:修复图片存入
BinaryField的逻辑错误
你当前直接把cv2.imread的返回值赋值给字段是错误的,cv2.imread返回的是Numpy数组,不能直接存入BinaryField,需要先转成二进制字节流,最后还要调用save()方法才会把数据写入数据库:
import cv2 import numpy as np # 读取图片后转二进制流 cv_img = cv2.imread(img_save_path) # 可根据需求调整存储格式为jpg等 _, img_encode = cv2.imencode('.png', cv_img) img_bytes = img_encode.tobytes() # 赋值后调用save保存 listing.restoredimage = img_bytes listing.save()
额外优化建议
- Django的
ImageField自带文件存储逻辑,不需要你手动写文件写入的代码,直接通过表单或者request.FILES把上传的图片赋值给listing.image,就会自动存到你配置的MEDIA目录下,更省代码 - 不推荐把图片直接存在数据库的
BinaryField里,会大幅增加数据库负载、拖慢查询速度,更合理的方案是把图片存在本地文件系统或者对象存储服务,数据库只存图片的访问路径
内容的提问来源于stack exchange,提问作者user1821998
相关产品推荐
相关产品推荐

