我正在尝试使用Valum的Ajax Upload在Django上进行文件上传 - 我正在制作的网站。目前我只是因为避免表格 AU将上载作为整个POST数据发送到ajax中 请求。现在我有一个非常天真的方法:
upload = SimpleUploadedFile( filename, request.raw_post_data )
...then I loop through the chunks to write to disk...
这对小文件很有用。我已经用各种PDF测试了 其他文件,以及高达~20MB的Google Chrome deb软件包和他们 一切都很好。但是,如果我升级到类似CD或DVD iso的东西 它可怕的炸弹。 Django经常发回内存不足 响应。从表面上看,这是有道理的,因为SimpleUploadedFile是 内存版本的上传类。我看不出怎么用 TemporaryUploadedFile因为它不占用其中的实际内容 构造函数。作为旁注:我会在用完之后想到 可用的RAM会用于虚拟内存,但无论如何。
所以,我的问题是,我该如何让它发挥作用?有没有更好的办法 读入文件?我试着通过直接读取raw_post_data Python的IO(系统使用2.6.5)但是FileIO的ascii编码器/解码器 在工作时,显然会抱怨非ascii字符 二进制文件。我一直无法找到有关改变的信息 编码器/解码器。
我不介意将数据传递到表单中并让Django执行此操作 选择正确的上传课程的工作等等,但我无法想象 如何传递它,因为像
这样的东西upload_form = UploadForm( request.POST, request.FILES )
不起作用,因为POST包含文件而不是正常文件 Django信息和文件不存在。
正如我所说的那样,我并不担心解决方案的方法 我得到了一些有用的东西!谢谢!
答案 0 :(得分:9)
如果有人有兴趣,我找到了两个解决方案。
第一种是纯Python的方式,这种方式适度成功。
with BufferedReader( BytesIO( request.raw_post_data ) ) as stream:
with BufferedWriter( FileIO( "/tmp/foo.bar", "wb" ) ) as destination:
foo = stream.read( 1024 )
while foo:
destination.write( foo )
foo = stream.read( 1024 )
它用于测试小文件(最多20MB),但是当我尝试使用ISO(~600MB)或更大的文件时失败了。我没有尝试20MB到600MB之间的任何东西,所以不确定断点在哪里。我已经复制了下面跟踪的底部,我不确定在这种情况下根本问题是什么。似乎有一个内存的困难,但我有足够的RAM +交换来保持文件三次,所以不知道为什么有一个问题。不确定使用其他形式的Python读/写或不使用缓冲区会有所帮助。
[error] [client 127.0.0.1] File "/usr/local/lib/python2.6 /dist-packages/django/core/handlers/wsgi.py", line 69, in safe_copyfileobj, referer: http://localhost/project/
[error] [client 127.0.0.1] buf = fsrc.read(min(length, size)), referer: http://localhost/project/
[error] [client 127.0.0.1] TemplateSyntaxError: Caught IOError while rendering: request data read error, referer: http://localhost/project/
对我所投入的所有内容都有效的解决方案,至少2GB文件,需要Django 1.3。他们为HttpRequest直接读取添加了类似文件的支持,所以我利用了它。
with BufferedWriter( FileIO( "/tmp/foo.bar", "wb" ) ) as destination:
foo = request.read( 1024 )
while foo:
destination.write( foo )
foo = request.read( 1024 )