2012-05-27 3 views
1

Я пытаюсь загрузить файл через формы django, а затем отправить его в API.Django transfer uploaded file

Вот функция кодирования:

#FYI, requestFile = request.FILES['file'] 
def EncodeFile(self, requestFile, fields = []): 

    BOUNDARY = '----------boundary------' 
    CRLF  = '\r\n' 
    body  = [] 
    # Add the metadata about the upload first 

    for param in fields: 
     body.extend(
      ['--' + BOUNDARY, 
      'Content-Disposition: form-data; name="%s"' % param, 
      '', 
      fields[param], 
      ]) 

    fileContent = requestFile.read() 

    body.extend(
     ['--' + BOUNDARY, 
     'Content-Disposition: form-data; name="file"; filename="%s"' 
     % requestFile.name, 
     # The upload server determines the mime-type, no need to set it. 
     'Content-Type: ' + requestFile.content_type, 
     '', 
     fileContent, 
     ]) 

    # Finalize the form body 
    body.extend(['--' + BOUNDARY + '--', '']) 
    result = 'multipart/form-data; boundary=%s' % BOUNDARY, CRLF.join(body) 
    return result 

Проблема заключается в том, что, когда он достигает «CRLF.join (тело)» жалуется на «„utf8“кодек не может декодировать байт 0xff в позиции 0: недействительна стартовый байт ".

Эта же часть кода работает безупречно из командной строки, за исключением того, что requestFile - это фактически путь к файлу, и перед чтением содержимого я делаю open (requestFile, 'rb').

Я не могу для жизни меня выяснить, что делать дальше. Я искал ответ за последние 10 часов или около того.

+0

Вы делаете что-либо с файловым потоком до вызова этой функции? Похоже, что указатель поиска не находится в начале потока. Что произойдет, если вы выполните 'requestFile.seek (0)' вверху? –

+0

Не делайте ничего с файлом перед тем, как попасть в эту функцию. Добавил requestFile.seek (0), как вы уже сказали. Та же ошибка. –

ответ

1

Видимо эта строка кода вызывает проблему:

'Content-Disposition: form-data; name="file"; filename="%s"' % requestFile.name, 

Правильная линия будет вместо:

'Content-Disposition: form-data; name="file"; filename="%s"' % smart_str(requestFile.name), 
0

Вы пытаетесь декодировать данные в строку и это не работает в функции соединения. Если django использует строгий режим, пытаясь декодировать данные, он выдает ошибку. ignore режим просто пропустит эти байты, это может объяснить, почему он работает с консоли).

Таким образом, вы не хотите, чтобы объект ответа был преобразован в строку юникода. Вы должны попытаться отладить функцию, которая пытается ее конвертировать и пытаться ее предотвратить. Функция join() не должна пытаться преобразовать ее в unicode.

Чтобы найти проблему, вы можете упростить ее таким образом, чтобы помочь найти причину. Это работает для меня в оболочке Python (но это должно вызывать такую ​​же ошибку в вашем случае):

body = ["1", "\xff"] 
result = 'multipart/form-data; boundary=%s' % BOUNDARY, CRLF.join(body) 
+0

К сожалению, это тоже не сработает. Я пробовал smart_str, smart_unicode и force_unicode. Ни один из них не работал. –

+0

@CiprianTarta Я изменил ответ, чтобы помочь вам переслать, вам нужно будет найти, какая функция пытается преобразовать его в unicode. – Lycha

+0

Если я делаю файл printContent перед добавлением его в тело с помощью метода body.extend (..., fileContent), я вижу двоичные данные в консоли. После выполнения этого метода содержимое кодируется. Это может быть проблемой, но как я могу ее предотвратить? Я пробовал делать append вместо расширения, даже нормального конкатенации строк. –