带有 MySQL 和 UTF-8 的 Django [重复]

Posted

技术标签:

【中文标题】带有 MySQL 和 UTF-8 的 Django [重复]【英文标题】:Django with MySQL and UTF-8 [duplicate] 【发布时间】: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.POST QueryDict 查找并替换/删除所有无效 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])

【问题讨论】:

【参考方案1】:

你有升级mysql的选项吗?如果你这样做,你可以升级并将编码设置为 utf8mb4。

假设您没有该选项,我会为您看到以下选项:

1) 添加 java 脚本/前端验证以防止输入 1,2 或 3 字节 unicode 字符以外的任何内容,

2) 在您的模型中添加清理功能以去除任何 4 字节 unicode 字符的数据(这将是您的选项 2 或 3)

同时,看起来您的用户实际上使用的是 4 字节字符。如果有在您的应用程序中使用它们的商业案例,您可以行使权力并请求升级。

【讨论】:

以上是关于带有 MySQL 和 UTF-8 的 Django [重复]的主要内容,如果未能解决你的问题,请参考以下文章

带有 mysql 和 django 的 Docker。尽管有任何尝试,都拒绝连接到 mysql

Django中的原始sql到json,带有日期时间和十进制MySql列

如何将带有中文字符的 CSV UTF-8 文件导入 MySQL?

我可以在带有 Python3.x 的 Django(dev 1.6.x) 上使用 MySQL 吗?

Django 1.8.2(使用 Python 3.4):如何将带有选项的 CharField 存储在带有 ENUM 列的 MySQL 表中?

带有 MySQL 非事务性更改表的 Django 无法回滚