python - Django:Unicode、MySQL 和编码(latin1、koi8-r)

标签 python mysql django encoding character-encoding

Django 2.0 版。 Python 3

我的数据库字符集和排序规则:

mysql> SELECT @@character_set_database, @@collation_database;
+--------------------------+----------------------+
| @@character_set_database | @@collation_database |
+--------------------------+----------------------+
| latin1                   | latin1_swedish_ci    |
+--------------------------+----------------------+

老开发者在KOI8-R中插入数据使用 Perl 编码 :(

为了从数据库中获取正确的值,我使用了丑陋的结构 str(username).encode('latin1').decode('koi8-r') .什么?我需要在我所有的项目中使用它来发送数据输出吗?或者编写函数来编码上下文字典,但我还需要额外的编码/解码所有数据。它会影响可用性和生产力

没有这个我会得到类似 ëÏÚÌÑÎËÏ òÏÍÁÎ éÏÓÉÆÏ×ÉÞ 的东西

如何在Django中全局设置编码,防止每处都进行encode/decode操作?我以不同的方式更改了编码,但没有任何反应。

在 settings.py 中,我尝试将 DEFAULT_CHARSET 设置为不同的编码(如果我将 default_charset 设置为 KOI8-R,我会得到一个错误:UnicodeEncodeError: 'charmap' codec can't encode characters in position 6228-6235: character maps to .使用其他编码没有错误但没有结果)。我试图在 settings.py 的数据库部分设置不同的字符集和排序规则值。

'OPTIONS': {
    'charset': 'latin1',
    'init_command': "SET sql_mode='STRICT_TRANS_TABLES', character_set_client=latin1, character_set_results=latin1, character_set_connection=latin1, collation_connection=latin1_swedish_ci",
}

我添加了 <meta http-equiv="Content-type" content="text/html; charset=koi8-r (or other)" /><head> index.html 模板中的标记。没有结果。

好像Django执行了SET NAMES utf8每次

为什么在 Perl 中我可以使用 charset=koi8-r 发送 header 并且我使用 CGI 从浏览器中的这个表中获取正常值?为什么在使用 Django 或 Flask 的 Python 中没有类似的结果? Simple example in Perl

最佳答案

我认为您混淆了网络字符编码和存储编码。在 MySQL 中,字符串数据的生命周期大致是这样的:

disk_storage --decode--> MySQL --encode--> network --decode--> database_driver

当从磁盘读取字符串数据时,MySQL 使用character_set_database 值对其进行解码。 当客户端通过网络连接时,客户端会为连接 指定编码。对于 Python,这通常是 UTF-8。 MySQL 然后将数据编码为连接编码。 然后,Python Mysql 驱动程序使用它设置的连接编码解码它接收到的数据。

如果这些解码或编码中的任何一个使用了错误的值,就会产生错误的数据。如果 character_set_database 设置不正确,则 MySQL 将在对网络连接上的错误数据进行编码之前错误地解码数据。

解决方案应该很简单,只需将character_set_database 更改为正确的值而不更改实际数据

这可以通过以下方式实现:

ALTER DATABASE dbname CHARACTER SET koi8r COLLATE koi8r_general_ci;

(不要运行 ALTER TABLE tbl_name CONVERT.. - 这实际上会重新编码您的数据。由于旧的 character_set 值错误,您的数据在编码为新编码之前将被错误解码)

将所有 Python 设置更改回默认值(UTF-8 等)。不要设置 DEFAULT_CHARSET 或任何其他值。

为确保 MySQL 驱动程序正确连接并使用 UTF-8 进行网络连接设置use_unicode=Truecharset="utf8"

例如

>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")

关于python - Django:Unicode、MySQL 和编码(latin1、koi8-r),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51537507/

相关文章:

django - Django 中的依赖注入(inject)

python - 如何将缩放比例放在三元图中的刻度上而不是 x 和 y 轴上

python - 在 python 源代码中查找 _collections

python - 带有值的堆叠条形图

Mysql需要选择多个条目数量最多的所有值

mysql - 使用 CAST 运算符将 VARCHAR 列排序为 FLOAT 在 MySQL 中不起作用

python - 未使用 WAMP SERVER Django/Mezzanine 在 MYSQL 中创建表

python - 使用 Tensorflow 作为 Anaconda 的环境

php - 在列中显示单行数据 mysql/PHP

django - 是否有可能达到 'measure' 的 django 模型实例的嵌套级别