Django Boto和上传到S3是400 Bad Request

时间:2011-12-20 07:15:18

标签: python django amazon-s3 boto

我正在尝试使用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,它适用于字符串数据。但是,处理文件或流的任何事情都会导致上述错误。我在某个地方错过了一个设置,或者我正在做的完全错误?

2 个答案:

答案 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}})。