使用ASIHTTPRequest将文件上载到django-piston

时间:2011-02-19 18:18:32

标签: django asihttprequest django-piston

我正在尝试使用ASIHTTPRequest将一些JSON和二进制文件从iPhone发布到运行django-piston的Django服务器

如果我只发送JSON字符串,我知道如何让它工作,如果我只发送文件,我知道如何使它工作,但两者都很棘手。

所以我们将从ASIHTTPRequest代码开始

ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:url];

[request setRequestMethod:@"POST"];

[request setPostFormat:ASIMultipartFormDataPostFormat];

[request appendPostData:[@"{\"save\":{\"name\":\"iostest\"}}" dataUsingEncoding:NSUTF8StringEncoding]];

[request addData:UIImageJPEGRepresentation([UIImage imageNamed:@"test.jpg"], 1.0f)
    withFileName:@"test.jpg"
  andContentType:@"image/jpeg"
          forKey:@"data"];

[request setDelegate:self];

[request startAsynchronous];

我最好的想法是将原始字符串数据直接添加到POST正文然后添加文件不起作用。

但如果我改为尝试

[request setPostValue:@"{\"name\":\"iostest\"}" forKey:@"save"];

然后活塞数据字典将['save']存储为字符串而不是反序列化的对象,因此它将字面上传递字符串

"{\"name\":\"iostest\"}"

这是我的Piston处理程序代码

def create(self, request):

     data = request.data

     print(data['save']) #{\"name\":\"iostest\"}"
     print("Files: " + request.FILES['data'].name) #test.jpg
     print("Data Save Name: " + data['save']['name']) #crash, interprets this as a string indeces lookup

欢迎提出意见。

2 个答案:

答案 0 :(得分:1)

  

我最好的想法是添加原料   字符串数据直接到POST正文   然后添加文件就没有了   工作

那不行,不。如果您使用'application / x-www-form-urlencoded'格式或'multipart / form-data'发布表单数据,那么您将无法在最后添加一些额外的数据 - 它需要作为表单数据的一部分进入。我估计这样的东西......

[request setPostValue:@"{\"save\":{\"name\":\"iostest\"}}" forKey:@"data"];

  

但是如果我删除字符串数据并且只发布文件它仍然无效。

更有问题...

  

或者活塞是否错误地误读了数据。

我可能不会首先考虑那个方向 - 活塞并没有真正弄乱请求对象,所以ASI请求似乎更有可能是不对的。

我认为开始的地方是检查传入的请求并检查它确实是一个有效的POST请求:

  1. 检查request["CONTENT_TYPE"]是否设置为'multipart / form-data'
  2. 检查request.raw_post_data并确保它是http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2中指定的有效表单数据 - 检查密钥名称是否符合预期并且文件内容是否存在。 (显然,当你测试它时,你会想要使用一个小文本文件!)
  3. 检查request.FILES中实际存在哪些密钥(如果有),以防它像错误的字段一样简单。
  4. 如果在客户端或服务器端出现问题,尝试编写普通的python客户端并查看是否存在相同的问题,那么我会尝试缩小范围。环顾四周,这样的事情:http://atlee.ca/software/poster/可能会有用。

答案 1 :(得分:1)

我基本上已经破解了这个方法。

基本问题是Django期望将文件提交到服务器的请求格式是django-piston字面上只是放下球的那个。

遇到多部分请求时,它根本不会尝试解析数据。

这个问题的解决方案是手动调用解析引擎,在JSON的情况下,它直接来自django.utils(这有点令人失望)。

您可以使用ASIHTTPRequest(或您选择的请求模块)按键设置标准帖子值,然后以旧式方式访问它。

from django.utils import simplejson
data = simplejson.loads(request.POST['save'])

在这一点上,基本上只是将这个处理程序方法简化为一个常规的旧Django视图,就你必须采取的步骤而言。

很明显,django-piston不是为了处理文件而构建的吗?