Raise ValueError('Имя файла должно быть строкой') ValueError: Имя файла должно быть строкой при загрузке файла на AWS S3 в Django
Я использовал Django для разработки веб-приложения. Во фронтенде пользователь должен загрузить изображение с помощью кнопки upload на AWS S3. Но я получил ошибку в s3_client.upload_file:
raise ValueError('Filename must be a string')
ValueError: Filename must be a string
view.py
def save_pic(request):
print("save_pic")
if request.method == 'POST':
image = request.FILES.get('image')
print(image)
img_name = image.name
ext = os.path.splitext(img_name)[1]
img_path = os.path.join(settings.IMG_UPLOAD, img_name)
with open(img_path, 'ab') as fp:
for chunk in image.chunks():
fp.write(chunk)
import boto3
from botocore.exceptions import ClientError
s3_client = boto3.client('s3', aws_access_key_id='XXX',
aws_secret_access_key='XXX', region_name='XXX')
try:
with open(img_path, 'rb') as fp:
response = s3_client.upload_file(fp, 'etp-tms', 'image_0.jpg')
except ClientError as e:
print(e)
try:
data = {'state': 1}
except:
data = {'state': 0}
return JsonResponse(data)
return JsonResponse(data="fail", safe=False)
HTML:
function renderCover(value, row) {
return '<input id="image-input" accept="image/*" type="file" />\n' +
'<img id="image-img" /> '
}
function upload() {
//alert("upload");
var formdata = new FormData();
formdata.append("image", $("#image-input")[0].files[0]);
formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());
$.ajax({
processData:false,
contentType:false,
url:'/save_pic/',
type:'post',
data:formdata,
dataType:"json",
success:function (arg) {
if (arg.state == 1){
alert('success')
}else {
alert('fail')
}
},error: function () {
alert("error")
}
})
}
когда я загружаю изображение, ошибка возникает на response = s3_client.upload_file(fp, 'etp-tms', 'image_0.jpg').:
raise ValueError('Filename must be a string')
ValueError: Filename must be a string
Согласно docs, функция upload_file
имеет три необходимых аргумента:
filename
, bucket
, object
.
Все они являются строками.
Ваш объект fp
не является именем файла, и это не строка. Вместо этого передайте в функцию имя файла.
Если вы уже открыли файл, используйте upload_fileobj
with open(img_path, 'rb') as fp:
response = s3_client.upload_fileobj(fp, 'etp-tms', 'image_0.jpg')
В противном случае перестаньте открывать файл самостоятельно и просто используйте upload_file
response = s3_client.upload_file(img_path, 'etp-tms', 'image_0.jpg')