搭建博客笔记:py_kouga (三) 解决异常: Incorrect string value错误

参考教程

  1. Django博客教程
  2. 自强学堂

激动地编辑了一篇测试文章,保存时报错了:“Django admin界面 Incorrect string value错误”。经排查,这是由于两个错误导致的:

  1. 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
  1. 查看 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

  1. 查看数据库的字符集并修改。
# 查看创建数据库的语句
show create database kouga;
 # 修改数据库的字符集
alter database kouga character set utf8;

修改数据库的摩默认字符集为 utf8 后,使用 Django 新建表也是 utf8.

  1. 查看表的字符集并修改。
show create table blog_post;
alter table blog_post character set utf8;
  1. 查看字段的字符集。
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 那一行了,说明修改有效果。于是,我觉得把这些表删掉重新生成。

  1. 删除有外键约束的表。
    直接删除表 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_%';
# 然后再一条条执行
  1. 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
  1. 依然抛出异常。
    我使用中文后台插入,依然抛出异常。
"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。

  1. 删除整个数据库,全部重新建。
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

你可能感兴趣的:(搭建博客笔记:py_kouga (三) 解决异常: Incorrect string value错误)