2012-05-27 60 views
1

我想通過Django的形式上傳文件,然後將其發送到API。Django傳輸上傳的文件

這裏的編碼功能:

#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(型)」,報告說「‘utf-8’編解碼器在0位置無法解碼字節0xFF:無效開始字節「。

完全相同的一段代碼完美地從命令行運行,但requestFile實際上是一個文件的路徑,並且在讀取內容之前我打開了一個open(requestFile,'rb')。

我不能爲了我的生活找出下一步該做什麼。過去10個小時左右,我一直在搜索Google的答案。

+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模式將跳過這些字節,這可能解釋爲什麼它似乎從控制檯工作)。

因此,您不希望將響應對象轉換爲unicode字符串。您應該嘗試調試哪個函數試圖將其轉換並嘗試阻止它。 join()函數不應該嘗試將其轉換爲unicode。

要找到問題,可以這樣簡化以幫助找到根本原因。這對我的作品在Python Shell(但應引起同樣的錯誤,你的情況):

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

如果我在使用body.extend(...,fileContent)方法將其添加到body中之前正在執行打印fileContent,則會在控制檯中看到二進制數據。在執行此方法後,內容將被編碼。這可能是問題,但我該如何防止它呢?我試着做append而不是擴展,即使是正常的字符串連接。 –