2017-06-16 95 views
0

我試圖使用Django rest框架從基於類的視圖中返回StreamingHttpResponse中的文件。不過,我得到一個堆棧跟蹤一個非常神祕的錯誤消息,不包含我的代碼的任何引用:Python UnicodeDecodeError:'ascii'編解碼器無法解碼位置12中的字節0xd0:序號不在範圍內(128)

16/Jun/2017 11:08:48] "GET /api/v1/models/49 HTTP/1.1" 200 0 
Traceback (most recent call last): 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 138, in run 
    self.finish_response() 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 179, in finish_response 
    for data in self.result: 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/util.py", line 30, in __next__ 
    data = self.filelike.read(self.blksize) 
    File "/Users/jonathan/anaconda/lib/python3.6/encodings/ascii.py", line 26, in decode 
    return codecs.ascii_decode(input, self.errors)[0] 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 12: ordinal not in range(128) 

[...] 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 141, in run 
    self.handle_error() 
    File "/Users/jonathan/anaconda/lib/python3.6/site-packages/django/core/servers/basehttp.py", line 88, in handle_error 
    super(ServerHandler, self).handle_error() 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 368, in handle_error 
    self.finish_response() 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 180, in finish_response 
    self.write(data) 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 274, in write 
    self.send_headers() 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 331, in send_headers 
    if not self.origin_server or self.client_is_modern(): 
    File "/Users/jonathan/anaconda/lib/python3.6/wsgiref/handlers.py", line 344, in client_is_modern 
    return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9' 
TypeError: 'NoneType' object is not subscriptable 

我get方法是這樣的:

def get(self, request, pk, format=None): 
    """ 
    Get model by primary key (pk) 
    """ 
    try: 
     model = QSARModel.objects.get(pk=pk) 
    except Exception: 
     raise Http404 
    filename = model.pluginFileName 
    chunk_size = 8192 
    response = StreamingHttpResponse(
        FileWrapper(open(filename), chunk_size), 
        content_type = 'application/zip') 
    return response 

從谷歌上搜索了一下我得到的感覺這與ASCII/UTF8編碼有關,但我不明白這是如何適用於我的情況。我正在處理一個二進制文件。實際上它是一個Java jar文件,但據我所知,它應該是一個zip文件。這裏發生了什麼,我做錯了什麼?

+1

我想,'開放(文件名,「RB」)'因爲你想處理的是字節(即:你不希望任何解碼發生),而不是文本將解決它... –

+0

是的,就是這樣。所以Python期望事情是ASCII,除非指定了其他東西。這有點令人驚訝... – jonalv

+0

嗯 - 無論解碼一個庫顯式執行或任何系統默認編碼是... –

回答

0

這與語言翻譯有關。當使用django存儲系統時不使用ascii文件名。因此,添加以下行在Apache envvars中

export LANG='en_US.UTF-8' 
export LC_ALL='en_US.UTF-8' 

https://code.djangoproject.com/wiki/django_apache_and_mod_wsgi#AdditionalTweaking

+0

這是因爲當不以二進制模式打開時,流傳輸響應的每個塊試圖解碼,因爲它一個zip文件和庫默認爲ASCII - 這是行不通的。以二進制模式打開文件可以返回純文本字節,而不會嘗試對其執行任何操作。 –

相關問題