将上传的图片存储到AWS S3

3

我有一个使用Python/Django编写的服务器应用程序(REST API),用于接受客户端应用程序上传的文件。我希望将这个上传的文件存储在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()

提前感谢


你有没有任何代码可以展示给我们,以便了解目前哪些部分是工作的或不工作的? - kchan
现在,我正在将文件上传到应用程序根文件夹。我想要更改并需要上传到AWS S3。 - Anish
请查看我下面发布的有关使用“django-storages”的答案。 - kchan
2个回答

3
如果您希望将上传的文件直接存储到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的存储后端(使用django-storages)的handle_uploaded_file方法来将上传的文件保存到远程目标。

注意:一定要在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()

在这里可以查看有关如何访问远程存储的更多解释和示例:


我已经阅读了链接,但我仍然有一个问题,如何从我的“FileUploadView”类将其上传到s3。如何更改“handle_uploaded_file”方法? - Anish
你能发布一下你正在使用的视图表单和相关模型吗?如果你定义一个字段来使用“FileField”或“ImageField”,存储后端将自动上传到你定义的存储目标。 - kchan
附加说明:但是,如果您的视图中的表单不直接存储到模型中(即不是ModelForm),那么您将需要使用存储后端手动存储/上传文件。并且在验证表单提交后,您可以在视图的处理代码中执行此操作。 - kchan
你能否发布处理上传的代码部分? - kchan
请查看我刚刚发布的示例代码。您可能需要根据自己的配置进行调整并进行一些测试。但这应该可以让您开始了解。 - kchan
显示剩余3条评论

-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()

请解释一下在 for i in range(1, <parts>): 和 for i in range(1, <parts>): 中的<parts>是什么意思。 - Anish
<parts> 是您将要获取的多部分上传数量... 这只是您可以执行的操作的指示,而不是最终代码... - AChampion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接