参考教程
激动地编辑了一篇测试文章,保存时报错了:“Django admin界面 Incorrect string value错误”。经排查,这是由于两个错误导致的:
- mysql 自身的设置
// 查看mysql 中关于字符的配置
mysql> select variables like "%char%";
参考文章,http://www.cnblogs.com/qwj-sysu/p/5400705.html。这样做是不太对的,重启之后无效了,应该修改配置文件才是根本。
如果里面有 "latin1"的,要修改配置。修改配置之前,要知道 mysql 的版本,不同的版本修改方案不同:
mysql -V
>>> mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper
在配置文件 /etc/mysql/mysql.cnf下根据不同版本指定字符集
[client]
default-character-set=utf8
[mysqld]
default-character-set=utf8 (mysql 5.1版本)
character-set-server=utf8(mysql 5.5 5.6 5.7版本)
然后重启数据库
/etc/init.d/mysql restart
- 查看 Django 的建表语句
show create table blog_post;
发现默认编码是latin1
CREATE TABLE `blog_post` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(70) NOT NULL,
`body` longtext NOT NULL,
`created_time` datetime(6) NOT NULL,
`modified_time` datetime(6) NOT NULL,
`excerpt` varchar(200) NOT NULL,
`author_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `blog_post_author_id_dd7a8485_fk_auth_user_id` (`author_id`),
KEY `blog_post_category_id_c326dbf8_fk_blog_category_id` (`category_id`),
CONSTRAINT `blog_post_author_id_dd7a8485_fk_auth_user_id` FOREIGN KEY (`author_id`) REFERENCES `auth_user` (`id`),
CONSTRAINT `blog_post_category_id_c326dbf8_fk_blog_category_id` FOREIGN KEY (`category_id`) REFERENCES `blog_category` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
搞到这,我有疑惑,到底是因为数据库默认设置是 lanti1
导致 django 建的表是CHARSET=latin1
还是 django 建表的时候会默认为 CHARSET=latin1
?所以,我尝试新建一张test
表来测试一下。
可参见教程:https://www.cnblogs.com/enjong/articles/8537531.html
- 查看数据库的字符集并修改。
# 查看创建数据库的语句
show create database kouga;
# 修改数据库的字符集
alter database kouga character set utf8;
修改数据库的摩默认字符集为 utf8 后,使用 Django 新建表也是 utf8.
- 查看表的字符集并修改。
show create table blog_post;
alter table blog_post character set utf8;
- 查看字段的字符集。
show full columns from blog_post;
结果显示,title 的Collation 是latin1_swedish_ci
, 这时我还用后台插入中文的话,依然会报错。
修改字段的字符集。
alter table blog_post change title title varchar(70) character set utf8 collate utf8_general_ci;
我再次向后台插入中文,还是报错,但是错误不在 title 那一行了,说明修改有效果。于是,我觉得把这些表删掉重新生成。
- 删除有外键约束的表。
直接删除表 blog_post 会有下面的错误,因为这个表有外键约束。
mysql> drop table blog_post;
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
参考教程,https://blog.csdn.net/drdongshiye/article/details/78244198
mysql 有一个变量FOREIGN_KEY_CHECKS来检查表是不是有外键约束,
# 不检查外键约束
FOREIGN_KEY_CHECKS=0
# 检查外键约束
FOREIGN_KEY_CHECKS=1
所以,我们先关闭外键约束,就可以删除这些表了,删除之后再把 FOREIGN_KEY_CHECKS=1.
批量删除指定前缀的表:
很遗憾,目前没有这样的sql直接去执行,所以我们先批量生成删除指定前缀的表,然后再手动一条条执行。
# 生成sql
select concat('drop table', table_name, ';') from information_schema.tables where table_name like 'blog_%';
# 然后再一条条执行
- django 重新建表。
参见教程,https://blog.csdn.net/wangqi_qiangku/article/details/79017822
1.先到数据库把表删掉:drop table
2.注释Django中对应的Model
3.执行以下命令:
python manage.py makemigrations
python manage.py migrate --fake
4.去掉步骤2中的注释
5.执行以下命令:
python manage.py makemigrations
python manage.py migrate
- 依然抛出异常。
我使用中文后台插入,依然抛出异常。
"Incorrect string value: '\\xE5\\x8D\\x9A\\xE5\\xAE\\xA2...' for column 'object_repr' at row 1"
object_repr 这个字段很陌生啊,咋又错了呢,经百度得知,这是django_admin_log
里的一个字段。验证一下:
show full columns from django_admin_log;
果然是,而且还发现了熟悉的 latin1_swedish_ci。
- 删除整个数据库,全部重新建。
delete database kouga;
create database kouga;
# 验证一下
use kouga;
show tables;
删除 blog 下面的migrations 文件夹。
执行迁移命令:
# 这条命令的原理就是每次都会从 migrations 文件中比较最近一次的改动,没有此文件夹,则认为是初始化
python manage.py makemigrations blog
这条执行后,会在 django_migrations 表中添加记录
# 这条命令会执行 migrations 的操作,以 git 做比较,makemigrations 是把改动提交到本地, migrate 是把改动同步到远程数据库.
python manage.py migrate
重新创建管理员
python manage.py createsuperuser
网友评论