2015-04-04 174 views
2

我有一個用python/django(REST api)編寫的服務器應用程序,用於接受來自客戶機應用程序的文件上傳。我希望這個上傳的文件存儲在AWS S3中。我也希望文件作爲多部分表單/數據從客戶端上傳。我怎樣才能做到這一點。任何示例代碼應用程序將幫助我理解應該如何完成。請協助。將上傳的圖像存儲到AWS S3

class FileUploadView(APIView): 
    parser_classes = (FileUploadParser,) 

    def put(self, request, filename, format=None): 
     file_obj = request.data['file'] 
     self.handle_uploaded_file(file_obj) 
     return self.get_response("", True, "", {}) 

    def handle_uploaded_file(self, f): 
     destination = open('<path>', 'wb+') 
     for chunk in f.chunks(): 
      destination.write(chunk) 
     destination.close() 

在此先感謝

+0

你有任何代碼向我們展示了什麼是工作或沒有合適的工作適合你現在? – kchan 2015-04-04 18:03:53

+0

立即寫入,我將文件上傳到應用程序根文件夾..我想更改該文件,並且需要上傳到AWS s3 – Anish 2015-04-04 18:28:32

+0

請查看我在下面使用''django-storages''發佈的答案。 – kchan 2015-04-04 18:35:22

回答

-1

看看boto包,它提供了AWS的API:

from boto.s3.connection import S3Connection 
s3 = S3Connection(access_key, secret_key) 
b = s3.get_bucket('<bucket>') 
mp = b.initiate_multipart_upload('<object>') 
for i in range(1, <parts>+1): 
    io = <receive-image-part> # E.g. StringIO 
    mp.upload_part_from_file(io, part_num=i) 
mp.complete_upload() 
+0

請解釋爲什麼在範圍內(1,):和我在範圍內(1,): – Anish 2015-04-04 18:30:57

+0

''是您將要獲得的分段上傳的數量......這只是一個指示你可以做什麼,而不是最終的代碼... – AChampion 2015-04-04 18:49:11

2

如果你想你的上傳直接去AWS S3,您可以使用django-storages和將您的Django文件存儲後端設置爲使用AWS S3。

這將使你的Django項目,以透明地處理存儲於S3,而你不必手動您上傳的文件重新上傳到S3。

存儲設置

您將需要至少這些配置添加到您的Django設置:

# default remote file storage 
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' 

# aws access keys 
AWS_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY' 
AWS_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY' 
AWS_BUCKET_NAME = 'your-bucket-name' 
AWS_STORAGE_BUCKET_NAME = AWS_BUCKET_NAME 

示例代碼上傳存儲到遠程存儲

這是一個您使用Django存儲後端的handle_uploaded_file方法將視圖的修改版本保存到遠程文件stination(使用django-storages)。

注意:請務必在您的settings中定義DEFAULT_FILE_STORAGE和AWS密鑰,以便django-storage可以訪問您的存儲桶。

from django.core.files.storage import default_storage 
from django.core.files import File 

# set file i/o chunk size to maximize throughput 
FILE_IO_CHUNK_SIZE = 128 * 2**10 


class FileUploadView(APIView): 
    parser_classes = (FileUploadParser,) 

    def put(self, request, filename, format=None): 
     file_obj = request.data['file'] 
     self.handle_uploaded_file(file_obj) 
     return self.get_response("", True, "", {}) 

    def handle_uploaded_file(self, f): 
     """ 
     Write uploaded file to destination using default storage. 
     """ 
     # set storage object to use Django's default storage 
     storage = default_storage 

     # set the relative path inside your bucket where you want the upload 
     # to end up 
     fkey = 'sub-path-in-your-bucket-to-store-the-file' 

     # determine mime type -- you may want to parse the upload header 
     # to find out the exact MIME type of the upload file. 
     content_type = 'image/jpeg' 

     # write file to remote server 
     # * "file" is a File storage object that will use your 
     # storage backend (in this case, remote storage to AWS S3) 
     # * "media" is a File object created with your upload file 
     file = storage.open(fkey, 'w') 
     storage.headers.update({"Content-Type": content_type}) 
     f = open(path, 'rb') 
     media = File(f) 
     for chunk in media.chunks(chunk_size=FILE_IO_CHUNK_SIZE): 
      file.write(chunk) 
     file.close() 
     media.close() 
     f.close() 

參見如何訪問這裏的遠程存儲更多的解釋和例子:

+0

我閱讀了鏈接,但我仍然有一個問題,我怎麼能讓我從我的「FileUploadView」類上傳到S3。如何更改「handle_uploaded_file」方法? – Anish 2015-04-04 18:44:36

+0

您可以發佈您使用的視圖以及相關模型的表單嗎?如果您要定義一個字段來使用「FileField」或「ImageField」,則存儲後端會自動上傳到您定義的存儲目標。 – kchan 2015-04-04 18:50:10

+0

附加說明:但是,如果視圖中的表單沒有直接存儲到模型中(即不是ModelForm),那麼您將不得不使用存儲後端手動存儲/上載文件。在驗證表單提交後,您可以在視圖的處理代碼中執行此操作。 – kchan 2015-04-04 18:52:35