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

Django 2.0版.
Python 3

我的数据库charset和collat​​ion:

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

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

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

如果没有这个,我会得到一些类似于ÏÏÏ……………………………………………………………………………………………….

如何在Django中全局设置编码以防止在每个地方进行编码/解码操作?我改变了编码方式,没有任何反应.

在settings.py中,我尝试将DEFAULT_CHARSET设置为不同的编码(如果我将default_charset设置为KOI8-R,我会收到错误:UnicodeEncodeError:’charmap’编解码器无法编码位置6228-6235中的字符:字符映射到.使用其他编码没有错误,但没有结果).我尝试在settings.py的数据库部分设置charset和collat​​ion的不同值.

'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(或其他)”/>到< head> index.html模板中的标记.没有结果.

似乎Django每次都执行SET NAMES utf8

为什么在Perl中我可以使用charset = koi8-r发送标头,并且我使用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 = True和charset =“utf8”

例如.

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