我在Django上做了相当大的文件上传。文件大小通常为10MB-100MB。
我在Heroku上,我已经达到30秒的请求超时。
为了达到极限,Heroku的recommendation将从浏览器直接上传到S3。
亚马逊通过向您展示如何write an HTML form执行上传来记录此内容。
由于我在使用Django,而不是手工编写HTML,我使用django-uploadify-s3(example)。这为我提供了一个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等。
非常感谢!
答案 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。