Django Request 对象提供了一个类似文件的接口,因此您可以从中流式传输数据。但是,由于 Django 总是将整个请求读入内存(如果文件上传太大,则读入临时文件),因此您只能在收到整个请求后使用此 API。如果您的临时存储目录足够大,并且您不介意在服务器上缓冲数据,则不需要做任何特别的事情。只需将数据上传到视图内的 S3。不过要小心超时。如果上传到 S3 的时间过长,浏览器将收到超时。因此,我建议将临时文件移动到更永久的目录并通过工作队列(如Celery
.
如果您想通过服务器直接从客户端流式传输到 Amazon S3,我建议使用gevent
. 使用 gevent,您可以编写一个greenlet
从 a 读取queue
并写入 S3 的简单程序。该队列由从请求中读取的原始 greenlet 填充。
您可以使用特殊的上传 URL,例如http://upload.example.com/
部署该特殊服务器的位置。如果您设置 DJANGO_SETTINGS_MODULE 环境变量并处理中间件通常为您做的一些事情(数据库连接/断开、事务开始/提交/回滚、会话处理等),则可以从 Django 框架外部使用 Django 函数.
甚至可以在同一个 WSGI 容器中同时运行您的自定义 WSGI 应用程序和 Django。只需包装 Django WSGI 应用程序并拦截对/upload/
. 在这种情况下,我建议使用gunicorn
asgevent worker-class
服务器。
我对 Amazon S3 API 不太熟悉,但据我所知,您也可以直接从您的用户那里为文件上传生成一个临时令牌。这样,您根本不需要通过服务器传输数据。
编辑:您确实可以允许匿名上传到您的存储桶。请参阅有关此主题的此问题:S3 - 匿名上传 - 密钥前缀