2012-02-17 135 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