可能重複:
How to filter (or replace) unicode characters that would take more than 3 bytes in UTF-8?Django的與MySQL和UTF-8
背景:
我使用Django與MySQL 5.1和我有4麻煩字節在我的Web應用程序中導致致命錯誤的UTF-8字符。
我已經使用a script將我數據庫中的所有表和列轉換爲UTF-8,它修復了大多數unicode問題,但仍然存在4字節unicode字符的問題。由於noted elsewhere,MySQL 5.1不支持長度超過3個字節的UTF-8字符。
每當我在我的Django的網站上輸入一個4字節Unicode字符(例如)成的ModelForm形式驗證,然後類似以下的異常引發:
Incorrect string value: '\xF0\x9F\x80\x90' for column 'first_name' at row 1
我的問題:
在Django Web應用程序中使用MySQL 5.1數據庫避免由4字節UTF-8字符引起的致命錯誤的合理方法是什麼?
我已經考慮:
- 有選擇地停止MySQL的警告,以避免明確該錯誤信息(不知道這是否可行還)
- 創建中間件將尋找通過
request.POST
QueryDict
和替代/刪除所有無效的UTF8字符 - 以某種方式hook/alter/monkey在執行查詢之前爲輸出SQL查詢的機制輸出Django或MySQLdb以替換/刪除所有無效的UTF-8字符
例中間件替換無效字符(由this SO question啓發):
import re
class MySQLUnicodeFixingMiddleware(object):
INVALID_UTF8_RE = re.compile(u'[^\u0000-\uD7FF\uE000-\uFFFF]', re.UNICODE)
def process_request(self, request):
"""Replace 4-byte unicode characters by REPLACEMENT CHARACTER"""
request.POST = request.POST.copy()
for key, values in request.POST.iterlists():
request.POST.setlist(key,
[self.INVALID_UTF8_RE.sub(u'\uFFFD', v) for v in values])