[英]Is Django double encoding a Unicode (utf-8?) string?
我在Django中存儲並輸出一個ndash字符作為UTF-8時遇到了麻煩。
我從API獲取數據。 在原始格式中,在文本編輯器中檢索和查看時,給定的數據單元可能類似於:
"I love this detergent \u2013 it is so inspiring."
(\\ u2013–作為html實體)。
如果我直接從API獲得並在Django中顯示它,沒問題。 它在我的瀏覽器中顯示為長划線。 我注意到我必須進行decode('utf-8')
以避免“'ascii'編解碼器無法編碼字符”錯誤,如果我嘗試在我的視圖中對該文本執行某些操作。 根據Django調試工具欄的說法,文本將作為“我喜歡這種洗滌劑,它非常鼓舞人心。”的模板。
然而,當存儲到MySQL並通過相同的視圖和模板讀取輸出時,它最終看起來像
"I love this detergent – it is so inspiring"
我的MySQL表設置為DEFAULT CHARSET=utf8
。
現在,當我通過設置為Utf-8的終端中的MysQl監視器從數據庫中讀取數據時,它顯示為
"I love this detergent – it is so inspiring"
(正確 - 顯示ndash)
當我在python shell中使用mysqldb時,這一行是
"I love this detergent \xe2\x80\x93 it is so inspiring"
(這是ndash的正確UTF-8)
但是 ,如果我運行python manage.py shell
,然后
In [1]: import myproject.myapp.models ThatTable
In [2]: msg=ThatTable.objects.all().filter(thefield__contains='detergent')
In [3]: msg
Out[4]: [{'thefield': 'I love this detergent \xc3\xa2\xe2\x82\xac\xe2\x80\x9c it is so inspiring'}]
在我看來,Django已經將\\xe2\\x80\\x93
表示為三個單獨的字符,並將其編碼為UTF-8到\\xc3\\xa2\\xe2\\x82\\xac\\xe2\\x80\\x9c
。 這顯示為 - 因為\\ xe2似乎是â,\\ x80似乎是€等等。我已經檢查過,這也是它被發送到模板的方式。
但是,如果使用decode('utf-8')
Python中的長序列,結果是\\xe2\€\“
,它也會在瀏覽器中呈現為 - 。 嘗試再次解碼會產生UnicodeDecodeError。
據我所知,我已經遵循了Django對Unicode的建議 (配置了MySQL)。
關於我可能錯誤配置的任何建議?
增編似乎同樣的問題在其他領域或系統也隨之而來還有,作為同時尋找\\ XC3 \\ XA2 \\ XE2 \\ X82 \\西飛\\ XE2 \\ X80 \\ x9c,我發現在http://pastie.org/ 908443.txt一個腳本來“修復壞的UTF8實體。”,也可以在wordpress RSS導入插件中找到。它只是用 - 替換這個序列。 不過,我想以正確的方式解決這個問題!
哦,我正在使用Django 1.2和Python 2.6.5。
我可以使用PHP / PDO連接到同一個數據庫並打印出這些數據而不做任何特殊操作,看起來很好。
這似乎是雙重編碼的情況; 我對Python沒有太多經驗,但請根據http://tahpot.blogspot.com/2005/06/mysql-and-python-and-unicode.html上的建議嘗試調整MySQL連接設置。
我猜測正在發生的是連接是latin1,所以MySQL嘗試在存儲到UTF-8字段之前再次對字符串進行編碼。 那里的代碼,特別是這一點:
編輯:使用Python建立數據庫連接時添加以下標志:init_command ='SET NAMES utf8'。
另外在MySQL的my.cnf中設置以下內容:default-character-set = utf8
可能就是你想要的。
我在我的php數據插入序列中添加了set names utf8
,現在在Python shell中,可怕的ndash顯示為\\ x96。 當通過Django讀取和輸出時,這會正確呈現。
關於這一點的一個不尋常的情況是我通過PHP插入數據。 Django會自動set names utf8
,所以如果我通過Django插入和讀取數據,那么這個問題就不會出現了。 我想,PHP使用的是默認的latin1
有趣的是,在我從PHP讀取數據並且它在瀏覽器中正常顯示之前,現在ndash是 ,除非我在讀取數據之前調用set names
。
所以,它現在正在運作,我希望我從來不需要了解之前發生的事情!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.