Загрузка файлов в Django-поршень с ASIHTTPRequest - PullRequest
2 голосов
/ 19 февраля 2011

Я пытаюсь отправить JSON и двоичный файл с iPhone на сервер Django с запущенным django-поршнем, используя ASIHTTPRequest

Я знаю, как заставить его работать, если я ТОЛЬКО отправляю строки JSON, и я знаю, как заставить его работать, если ТОЛЬКО отправляю файл, но делать то и другое сложно.

Итак, начнем с кода запроса ASIHTTP

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\"}"

Вот мой код обработчика поршня

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 ]

1 голос
/ 22 февраля 2011

Я в основном взломал этот способ.

Основная проблема заключается в том, что формат запроса, в котором Django ожидает, что файлы будут отправлены на сервер, - это тот формат, в котором django-pneon буквально просто отбрасывает мяч.

Когда он встречает многочастные запросы, он просто не пытается проанализировать данные.

Решение этой проблемы состоит в том, чтобы вручную вызвать механизм синтаксического анализа, который, в случае JSON,прямо из django.utils (что отчасти разочаровывает).

Этого можно добиться, используя ASIHTTPRequest (или модуль запроса по вашему выбору), чтобы установить стандартное значение post по ключу, а затем получить к нему доступстаромодным способом.

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

Который на данный момент сводит этот метод-обработчик к не более чем обычному старому представлению Django с точки зрения шагов, которые вы должны предпринять, чтобы его запустить.

Итак, очевидно, что django-поршень не предназначен для работы с файлами?

1 голос
/ 21 февраля 2011

Моя лучшая идея в том, чтобы добавить сырье строковые данные непосредственно в тело POST а затем добавление файла просто не работа.

Это не сработает, нет. Если вы отправляете данные формы POST в формате application / x-www-form-urlencoded или multipart / form-data, вы не сможете просто добавить некоторые дополнительные данные в конце - это необходимо войти как часть данных формы. Как-то так, наверное ...

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

Но если я удалю строковые данные и отправлю только файл, он все равно не будет работать.

Это более проблематично ...

или, если Piston ошибочно неверно истолковывает данные.

Вероятно, я бы не стал сначала смотреть в этом направлении - поршень на самом деле не связывается с объектом запроса, поэтому более вероятно, что запрос 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, если таковые имеются, на случай, если это так просто, как что-то вроде поля с неправильным названием.

Если все это не удастся, я попытаюсь сузить, если это проблема на стороне клиента или сервера, попытавшись написать простой клиент Python и выяснить, есть ли у вас такая же проблема. Оглядываясь вокруг, можно примерно так: http://atlee.ca/software/poster/ может быть полезно.

...