2012-05-22 54 views
3

我有一個unicode名稱的文件(例如中文字符)。我得到一個UnicodeEncodeError。我在utf8中使用postgres數據庫,在ubuntu lucid 64上使用django開發服務器。我錯過了什麼?我做了以下filename是在models.py文件的Unicode名稱:用unicode文件名上傳文件

def get_upload_path(instance,filename): 
    return filename # Unicode error if filename has non latin 1 characters 

class Kind (models.Model): 
    style = models.ForeignKey(Style) 
    kind_file = models.FileField(upload_to=get_upload_path) 

從外殼:

enter image description here

+0

你在哪些方面得到例外?我相當確定這是在你的「slugify」呼叫。 – birryree

+0

我在代碼示例中添加了一些細節。 slugify的作品,但是當我嘗試將這兩個字符串連接在一起時,它不起作用 – prostock

+1

這應該會幫助您瞭解隱藏的內容:http://bit.ly/unipain – Daenyth

回答

3

我相信這個問題是你的字符串格式化。在python2中,它會自動在str類型(這是一系列字節)和unicode類型之間進行轉換,它表示unicode代碼點的抽象序列。

我假設你的filenameunicode類型。

"tmp/%s/%s"是一個字節的字符串,所以Python會自動編碼unicodestr相匹配。問題是它使用ascii編碼來實現,因爲它不能保存您的數據。

將您的return聲明更改爲使用temp2而不是filename應該可行,因爲現在您一起使用了正確的類型。


對於未來,我也建議看我掛在評論中陳述,因爲它提供了多種策略,以避免此類問題。主要的一點是,當你的程序以外的地方發送數據時,你應該只使用字節。只要你從外部接收字節,decode他們unicode,並且只有encode當你從你的程序發送數據。你還應該在內部使用unicode字符串文字(u""而不是"")。

我還建議比tempN更有意義的變量名稱。

+0

感謝您的幫助。我經歷了unicode的演示文稿,這是有道理的,但事情仍然不起作用。文件名已經是類型unicode。即使我只返回文件名,它仍然給我Django的Unicode錯誤。有任何想法嗎? – prostock

+0

django可能需要'str'作爲你的返回值。 'FileField'的文檔沒有指定你的返回值應該是什麼類型,它只是說「一個unix樣式的路徑」。 – Daenyth

+0

我試圖先用.encode('utf-8')將它轉換爲一個字節字符串,但後來我得到錯誤'DjangoUnicodeDecodeError:'utf8'編解碼器無法解碼位置1-3中的字節:無效數據。您已通過「'\ xe5 \\ x84 \\ xb7 \ xe5 \\ xae \\ x8b Pro。ttf'「()' – prostock