我正在尝试使用boto库创建一个超级简单的文件上载脚本,而不是其他任何库。根据我的尝试,它感觉它应该工作,但事实并非如此。
我现在得到的错误是:
S3ResponseError: 400 Bad Request
以下是我在视图中的代码:
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
file = request.FILES['file']
filename = file.name
conn = boto.connect_s3()
bucket = conn.create_bucket('some-bucket-name')
from boto.s3.key import Key
k = Key(bucket)
k.key = filename
k.send_file(file)
k.content_type = mimetypes.guess_type(filename)[0]
k.set_contents_from_stream(file.chunks())
k.set_acl('public-read')
return HttpResponseRedirect('/')
else:
form = UploadFileForm()
return render_to_response('home/upload.html',
{'form':form},
context_instance=RequestContext(request))
如果我将其修改为本地保存,则可以正常上传到s3。我测试了set_contents_from_string
,它适用于字符串数据。但是,处理文件或流的任何事情都会导致上述错误。我在某个地方错过了一个设置,或者我正在做的完全错误?
答案 0 :(得分:2)
我遇到了尝试将文件传输到S3的确切问题。最后,我发现我必须在size
对象之前设置Key
属性才能调用send_file
。
k = Key(bucket)
k.key = 'some-key'
k.size = 12345
k.send_file(file)
可以使用文件中的seek和tell找到大小。以下将在保留当前文件位置的同时找到大小。在您的情况下,您可以省去记住当前位置,并在获得文件大小后回寻零。
position = file.tell()
file.seek(0, os.SEEK_END)
size = file.tell()
file.seek(position)
答案 1 :(得分:0)
我倾向于在shell中测试你的s3连接和存储桶创建步骤。
python manage.py shell
我很好奇是否是那些绊倒你的步骤。例如,如果您指定的存储桶名称不是全局唯一的,则会收到错误(不确定是否会导致您收到的错误代码,但这是我要检查的第一个地方)。
如果这是问题,您可以考虑在AWS管理控制台中设置存储桶,然后从您的视图连接到该存储桶,并根据项目需要使用适当的“类文件夹”键上传文件(请参阅:{ {3}})。