Django后端用PIL处理上传图片时出现AttributeError报错
Django处理上传图片时AttributeError错误解决
错误信息
<class 'AttributeError'> 347 '_io.BufferedRandom' object has no attribute 'getvalue'
相关代码
try: if 'image' in request.FILES['image'].content_type: image = request.FILES['image'] image_name = profile["user"] + "." + image.name.split(".")[1] image_value = image.file.getvalue() with Image.open(image) as im: if (getattr(im, "is_animated", False)): if profile.premium: print("premium image posted") updated_profile['pfp'] = image_name functions.upload_image("pfp", image_value, image_name) else: print("premium error") messages.error(request, "You need premium for animated posts!") else: print("image posted") updated_profile['pfp'] = image_name functions.upload_image("pfp", image_value, image_name) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() print(exc_type, exc_tb.tb_lineno) print(e)
报错原因
request.FILES['image'].file是_io.BufferedRandom类型的磁盘文件流,这个对象没有getvalue()方法——getvalue()是内存字节流BytesIO的专属方法。直接调用磁盘文件流的getvalue(),就会触发AttributeError。
解决方法
方法1:用read()读取内容并重置指针
直接调用read()读取文件内容,读取后必须将文件指针重置到开头,否则后续Image.open(image)会因为指针在文件末尾而读不到内容:
# 替换原来的image_value = image.file.getvalue() image_value = image.file.read() # 重置文件指针到起始位置 image.file.seek(0)
方法2:转成BytesIO处理
如果需要使用getvalue(),可以先将磁盘文件流转成内存中的BytesIO对象,同样要注意重置原文件指针:
from io import BytesIO # 读取文件内容到BytesIO image_bytes = BytesIO(image.file.read()) image_value = image_bytes.getvalue() # 重置原文件指针,保证后续Image.open能正常读取 image.file.seek(0) # 后续PIL打开可以用image_bytes或者原image对象 with Image.open(image_bytes) as im: # 原有处理逻辑不变
修改后的完整代码示例
try: if 'image' in request.FILES['image'].content_type: image = request.FILES['image'] image_name = profile["user"] + "." + image.name.split(".")[1] # 替换报错的行,使用方法1实现 image_value = image.file.read() image.file.seek(0) with Image.open(image) as im: if (getattr(im, "is_animated", False)): if profile.premium: print("premium image posted") updated_profile['pfp'] = image_name functions.upload_image("pfp", image_value, image_name) else: print("premium error") messages.error(request, "You need premium for animated posts!") else: print("image posted") updated_profile['pfp'] = image_name functions.upload_image("pfp", image_value, image_name) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() print(exc_type, exc_tb.tb_lineno) print(e)
内容的提问来源于stack exchange,提问作者kipteam
相关产品推荐
相关产品推荐

