14

背景

我正在 Django 上上传相当大的文件。文件大小一般为10MB-100MB。

我在 Heroku 上,我一直在达到 30 秒的请求超时。

开始

为了绕过限制,Heroku 的建议是从浏览器直接上传到 S3。

亚马逊通过向您展示如何编写HTML 表单来执行上传来记录这一点。

由于我使用的是 Django,而不是手动编写 HTML,我使用的是django-uploadify-s3示例)。这为我提供了一个包裹在 JS 中的 SWF 对象,它执行实际的上传。

这部分工作正常!万岁!

问题

问题在于以一种理智的方式将这些数据绑定回我的 Django 模型。现在数据作为一个简单的 URL 字符串返回,指向文件的位置。

但是,我之前使用django-storages 的 S3 Boto来管理我的所有文件FileFields,由令人愉快的S3BotoStorageFile.

重申一下,S3 Boto 单独运行良好,Uploadify 单独运行良好,问题在于将两者放在一起。

我的理解是,填充的唯一方法FileField是同时提供文件名和文件内容。当您将文件从浏览器上传到 Django 时,这没问题,因为 Django 将文件内容放在缓冲区中,并且可以随心所欲地使用它。但是,当像我一样进行直接到 S3 的上传时,Django 只接收文件名和 URL,而不是二进制数据,所以我无法正确填充FieldFile.

求救

有人知道将 S3Boto 的 FileField 与直接到 S3 上传结合使用的优雅方式吗?

否则,仅基于 URL 管理 S3 文件的最佳方法是什么?包括设置过期时间、key id等。

非常感谢!

4

6 回答 6

1

使用URLField

于 2012-03-19T01:15:30.783 回答
1

这是未经测试的,但您应该能够使用:

from django.core.files.storage import default_storage
f = default_storage.open('name_you_expect_in_s3', 'r')
#f is an instance of S3BotoStorageFile, and can be assigned to a field
obj, created = YourObject.objects.get_or_create(**stuff_you_know)
obj.s3file_field = f
obj.save()

我认为这应该设置指向 s3 的本地指针并保存它,而不是过度写入内容。

ETA:只有在 S3 上完成上传并且您知道 s3 中的密钥后,您才应该这样做。

于 2013-10-29T17:00:14.310 回答
1

我有一个类似的问题,我想直接使用 FileField 将文件存储到 s3,或者我可以选择让用户直接输入 url。所以为了避免这种情况,我在模型中使用了 2 个字段,一个用于 FileField,一个用于 URLField。在模板中,我可以使用“或”来查看存在哪一个并使用 {{ instance.filefield 或 instance.url }}。

于 2012-04-22T14:38:23.023 回答
0

出 django-filetransfers。看起来它与 django-storages 配合得很好。

于 2013-07-02T18:35:38.913 回答
-1

我认为编写实际的 SQL 可能是这里最简单的解决方案。或者,您可以将 S3BotoStorage 子类化,覆盖 _save 方法并允许一个可选的文件路径 kwarg,它回避所有其他保存的东西,只返回 clean_name。

于 2012-08-19T06:55:28.920 回答
-1

我从来没有使用过 django,所以 ymmv :) 但为什么不只写一个字节来填充内容呢?这样,您仍然可以使用 FieldFile。

于 2012-03-16T00:00:04.870 回答