You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python/Django后端本地图片上传至S3报错解决方案咨询

解决Django后端本地文件上传S3的问题

问题根源

你当前代码的核心问题是用文本模式打开图片文件——图片属于二进制数据,encoding="utf-8"会导致文件读取异常,同时如果后续操作期望带file属性的文件对象(比如Django的UploadedFile),直接传字节流或文本流就会触发'bytes' object has no attribute 'file'这类错误。

修正方案

方案1:直接用boto3正确读取二进制文件上传

把文件打开模式改成'rb'(二进制只读),读取正确的二进制数据后直接传给put_object:

# 用rb模式打开二进制文件,去掉encoding参数
with open(fileURL, 'rb') as image:
    S3_BUCKET = settings.AWS_BUCKET
    session = boto3.Session(
        aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
        aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
    )
    s3 = session.resource('s3')
    s3.Bucket(S3_BUCKET).put_object(Key=f'folder/{fileName}', Body=image)

用with语句能自动关闭文件,避免资源泄漏。

方案2:包装成Django文件对象(兼容表单上传逻辑)

如果你的代码复用了前端表单上传的处理函数(这类函数通常期望Django的File对象),可以把本地文件包装成django.core.files.File:

from django.core.files import File

with open(fileURL, 'rb') as f:
    # 包装成Django标准File对象
    django_file = File(f)
    # 复用表单上传的存储逻辑(需提前配置S3为默认存储)
    from django.core.files.storage import default_storage
    file_path = default_storage.save(f'folder/{fileName}', django_file)

这种方式无需直接操作boto3,更符合Django开发习惯。

额外注意事项

  • 确保fileURL是本地文件的绝对路径,避免路径找不到的错误。
  • 检查AWS权限:配置的Access Key必须拥有S3的PutObject权限。
  • 上传大文件时,建议用upload_file替代put_object,支持分块上传:
s3.meta.client.upload_file(fileURL, S3_BUCKET, f'folder/{fileName}')

内容的提问来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:42:21