Django Boto上传到S3时出现400坏请求

1 投票
2 回答
3326 浏览
提问于 2025-04-17 08:41

我正在尝试用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

我建议你在命令行里测试一下你的S3连接和创建存储桶的步骤。

可以用这个命令:python manage.py shell

我想知道是不是这几个步骤让你遇到了问题。比如说,如果你指定的存储桶名称不是全球唯一的,你就会收到一个错误(我不确定这是否会导致你收到的错误代码,但这是我会首先检查的地方)。

如果真的是这个问题,你可以考虑在AWS管理控制台里先创建一个存储桶,然后从你的视图中连接到这个存储桶,并根据你项目的需要使用合适的“文件夹样式”的键来上传文件(可以参考这个链接:Amazon S3 boto - 如何创建文件夹?)。

2

我在尝试把文件传到S3的时候遇到了这个问题。最后我发现,我需要在调用 send_file 之前,先设置 Key 对象的 size 属性。

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)

撰写回答