我正在实现一个REST风格的接口,希望能够通过HTTP PUT请求创建(通过上传)文件。我想创建一个TemporaryUploadedFile
或InMemoryUploadedFile
,然后我可以将其传递到作为模型一部分的对象上的现有FileField
和.save()
,从而存储文件。
我不太清楚如何处理文件上传部分。具体来说,这是一个put请求,我无权访问request.FILES
,因为它不存在于PUT
请求中。
所以,有些问题:
HttpRequest
类中的现有功能,特别是处理文件上载的部分?我知道directPUT
不是一个多部分MIME请求,所以我不这么认为,但值得一问。TemporaryUploadFile
和相关代码所做的事情-一次只写一部分?我看了一下this code sample,它诱使Django将PUT
作为POST
请求处理。如果我没弄错的话,它只能处理表单编码的数据。这是REST,所以最好的解决方案是不要假设表单编码的数据会存在。不过,我很高兴听到关于以某种方式使用mime(而不是多部分)的适当建议(但是上传应该只包含一个文件)。
Django 1.3是可以接受的。所以我可以用request.raw_post_data
或者request.read()
(或者其他更好的访问方法)做些事情。有什么想法吗?
你不想触碰
request.raw_post_data
-这意味着将整个请求体读入内存,如果你在讨论文件上传可能会有很大的量,所以request.read()
才是正确的方法。在Django<;=1.2的情况下也可以这样做,但这意味着在HttpRequest
中寻找正确的方法来使用私有接口,这是一个真正的阻力,可以确保代码也与Django>;=1.3兼容。我建议您要做的是复制existing file upload behaviour parts of the ^{} class :
request.upload_handlers
(默认为MemoryFileUploadHandler
&;TemporaryFileUploadHandler
)检索上载句柄HttpRequest
或MultiPartParser
中搜索内容长度以查看正确的方法。)handler.new_file
(模拟字段名)request.read()
并为每个块调用handler.receive_data_chunk()
以块形式读取请求正文。handler.file_complete()
,如果它返回一个值,那就是上传的文件。要么让客户端在内容类型头中指定它,要么使用python's mimetype module猜测媒体类型。
我很想知道你是怎么处理这件事的-这是我一直想调查自己的事情,如果你能评论让我知道它是怎么回事就好了!
由Ninefingers编辑根据要求,这是我所做的,完全基于上述内容和django来源。
既然我在这里定义了API,跨浏览器支持就不再是问题了。就我的协议而言,不提供正确的信息是一个坏请求。我对是否要说
image/jpeg; charset=binary
或是否允许不存在的字符集有两种看法。无论如何,我把设置Content-Type
有效地作为客户端的责任。类似地,对于我的协议,文件名被传入。我不确定
field_name
参数的用途,而且源代码没有给出太多线索。下面发生的事情实际上比看起来简单得多。询问每个处理程序是否将处理原始输入。作为上述状态的作者,默认情况下您拥有
MemoryFileUploadHandler
&;TemporaryFileUploadHandler
。好吧,当被要求创建一个new_file
时MemoryFileUploadHandler
将决定它是否处理该文件(基于各种设置)。如果它决定要这样做,它会抛出一个异常,否则它不会创建文件并让另一个处理程序接管。我不知道
counters
的目的是什么,但我一直不知道它的来源。其余的应该是直截了当的。由于https://gist.github.com/g00fy-/1161423,较新的Django版本允许更轻松地处理这个问题
我这样修改了给定的解决方案:
能够访问POST中的文件和其他数据。如果希望数据是只读的,可以删除对
.dict()
的调用。相关问题 更多 >
编程相关推荐