如何混合Django,Uploadify和S3Boto存储后端?

时间:2012-03-15 23:16:38

标签: django amazon-s3 uploadify boto filefield

背景

我在Django上做了相当大的文件上传。文件大小通常为10MB-100MB。

我在Heroku上,我已经达到30秒的请求超时。

开始

为了达到极限,Heroku的recommendation将从浏览器直接上传到S3。

亚马逊通过向您展示如何write an HTML form执行上传来记录此内容。

由于我在使用Django,而不是手工编写HTML,我使用django-uploadify-s3example)。这为我提供了一个SWF对象,用JS包装,执行实际的上传。

这部分工作正常!万岁!

问题

问题正在以理智的方式将数据绑定回我的Django模型。 现在,数据以简单的URL字符串形式返回,指向文件的位置。

但是,我以前使用S3 Boto from django-storages将所有文件作为FileFields管理,并由令人愉快的S3BotoStorageFile支持。

重申一下,S3 Boto在孤立方面工作得很好,上传它在隔离方面工作得很好,问题在于将两者结合在一起。

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

寻求帮助

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

否则,基于其URL管理S3文件的最佳方法是什么?包括设置过期,密钥ID等。

非常感谢!

6 个答案:

答案 0 :(得分:1)

使用URLField

答案 1 :(得分:1)

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

答案 2 :(得分: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中的密钥后才能执行此操作。

答案 3 :(得分:0)

结帐django-filetransfers。看起来它与django-storage一起玩得很好。

答案 4 :(得分:-1)

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

答案 5 :(得分:-1)

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