Reputation: 41
I have used Django to develop a web app. In the frontend, the user is supposed to upload an image by upload button to AWS S3. But I got the error at 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")
}
})
}
when I upload the img, the error occurs at response = s3_client.upload_file(fp, 'etp-tms', 'image_0.jpg').:
raise ValueError('Filename must be a string')
ValueError: Filename must be a string
Upvotes: 0
Views: 2000
Reputation: 23206
If you already opened the file, use upload_fileobj
with open(img_path, 'rb') as fp:
response = s3_client.upload_fileobj(fp, 'etp-tms', 'image_0.jpg')
Otherwise, stop opening the file yourself and simply use upload_file
response = s3_client.upload_file(img_path, 'etp-tms', 'image_0.jpg')
Upvotes: 1