【发布时间】:2012-10-18 08:45:54
【问题描述】:
可能重复:
How to filter (or replace) unicode characters that would take more than 3 bytes in UTF-8?
背景:
我将 Django 与 MySQL 5.1 一起使用,我遇到了 4 字节 UTF-8 字符的问题,导致整个 Web 应用程序出现致命错误。
我已使用a script 将我数据库中的所有表和列转换为 UTF-8,它已修复了大多数 unicode 问题,但 4 字节 unicode 字符仍然存在问题。如noted elsewhere,MySQL 5.1 不支持长度超过 3 个字节的 UTF-8 字符。
每当我在我的 Django 网站上的 ModelForm 中输入一个 4 字节的 unicode 字符(例如 ????)时,表单都会验证,然后引发类似于以下内容的异常:
Incorrect string value: '\xF0\x9F\x80\x90' for column 'first_name' at row 1
我的问题:
在具有 MySQL 5.1 数据库的 Django Web 应用程序中,避免由 4 字节 UTF-8 字符引起的致命错误的合理方法是什么。
我考虑过:
- 有选择地禁用 MySQL 警告以专门避免该错误消息(不确定这是否可能)
- 创建将通过
request.POSTQueryDict查找并替换/删除所有无效 UTF8 字符的中间件 - 以某种方式挂钩/更改/猴子修补为 Django 或 MySQLdb 输出 SQL 查询的机制,以在执行查询之前替换/删除所有无效的 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])
【问题讨论】:
标签: mysql django utf-8 mysql-5.1 utf8mb4