2012-02-17 138 views
3

我有一个关于从客户端(在这种情况下是iPhone应用程序)上传到S3的一般性问题。我使用Django在EC2实例上编写web服务。下面的方法是最低限度,以将文件上传到S3,它工作得很好,更小的文件(JPG格式或PNG < 1 MB):图片上传:iPhone客户端 - Django - S3

def store_in_s3(filename, content): 
    conn = S3Connection(settings.ACCESS_KEY, settings.PASS_KEY) # gets access key and pass key from settings.py 
    bucket = conn.create_bucket('somebucket') 
    k = Key(bucket) # create key on this bucket 
    k.key = filename 
    mime = mimetypes.guess_type(filename)[0] 
    k.set_metadata('Content-Type', mime) 
    k.set_contents_from_string(content) 
    k.set_acl('public-read') 

def uploadimage(request, name): 
    if request.method == 'PUT': 
     store_in_s3(name,request.raw_post_data) 
     return HttpResponse("Uploading raw data to S3 ...") 
    else: 
     return HttpResponse("Upload not successful!") 

我很新的这一切,所以我还是不明白这里发生了什么。是这样的情况:

  • Django收到文件并将其保存在我的EC2实例的内存中?
  • 我应该避免使用raw_post_data,而是使用块来避免内存问题?
  • 一旦Django收到文件,它会将文件传递给函数store_in_s3吗?
  • 我如何知道上传到S3是否成功?

所以一般来说,我不知道我的代码中的一行是否会在另一行之后执行。例如。什么时候会火return HttpResponse("Uploading raw data to S3 ...")?文件仍在上传或成功上传后?

感谢您的帮助。另外,我会很感激任何处理这个问题的文档。我看了O'Reilly的Python & AWS Cookbook中的章节,但由于它只是代码示例,它并不能真正回答我的问题。

回答

1

Django将小的上传文件存储在内存中。超过一定的大小,它会将其存储在磁盘上的临时文件中。

是,分块是节省内存以及帮助:

for file_chunk in uploaded_file.chunks(): 
    saved_file.write(file_chunk) 

所有这些操作是同步的,所以Django会等到文件完全在上传之前它会尝试将其存储在S3。 S3必须先完成上传才能返回,因此您可以保证它会通过Django上传到S3,然后您将收到您的HttpResponse()

Django的File Uploads文档有很多关于如何处理各种上传情况。

+0

谢谢,这真的很有帮助。我刚刚检查了几个其他帖子,似乎最好的解决方案是将客户端(iPhone)的东西直接上传到S3。这将使服务器快捷 - 并且不会像我所见到的那样创建双倍的流量(即,首先上传到EC2/Django,然后上传到S3)。 – 2012-02-18 09:36:05

+1

没错,唯一需要注意的是如果您对上传的图像进行了任何处理。在我的业务中,每个图像在Django服务器上调整为各种不同的大小,然后将每个图像上传到CDN。只是一个例子,但要记住你自己的应用程序。 – Jordan 2012-02-18 09:39:24

+0

我明白了。因此,如果我不在服务器上处理图像,那么直接使用Client-> S3即可。如果我需要做一些处理,我会通过Django服务器。非常感谢,这真的很有帮助。 – 2012-02-18 09:42:56

1

你可能想看看django-storages。它有助于在S3和其他一些服务/平台上存储文件。

+0

谢谢基思。我刚刚检查了一些其他帖子,似乎我应该直接从客户端(iPhone)上传东西到S3,而无需通过Django。在这种情况下,我想,我不需要django-storage。但谢谢你让我知道。 – 2012-02-18 09:37:30