2015-04-04 125 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