django解决中文乱码的困扰 -终极

情景:需要读取外部文件的信息,包括文件名、文件内容,如果都是英文、都是utf-8编码那就啥烦恼都没有了,现在的情况就是文件名会出现中文,文件内容也会出现中文并且编码还不一定是utf-8。

django表现:如果文件名包含中文,从后台传递到templates时会直接报错,如:DjangoUnicodeDecodeError: ‘utf8’ codec can’t decode…所以我们需要玩转python的编码(encode)与解码(decode)。

在文章的开始,还是推荐先看看这篇文章:
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431664106267f12e9bef7ee14cf6a8776a479bdec9b9000

我把最重点的摘出来:
1、我们最常接触到的编码有四种:Unicode、ASCII、UTF-8、GB2312;
2、在计算机内存中,统一使用Unicode编码;
3、用记事本编辑的时候,从文件读取的UTF-8(GB2312/ASCII)字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8(GB2312/ASCII)保存到文件;
4、如果要在网络上传输,或者保存到磁盘上,就需要把python字符串str变为以字节为单位的bytes,以Unicode表示的str通过encode()方法可以编码为指定的bytes;
5、反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法。
顺便借用一下原图:
在这里插入图片描述

从上面可知,有两个最重要的函数encode() 与 decode()。这时,我们都会想到:如何知道一个文件是使用何种编码格式呢?不用担心,python都替我们做好了:

import chardet

with open(sql_file, "r") as f:
	file_content = "".join(f.readlines())
	print chardet.detect(sql_file_content)

# 输出一个dict类型数据,我们只需关注 encoding 项:
# {'confidence': 0.99, 'language': 'Chinese', 'encoding': 'GB2312'}         

开始解决我们的问题,现假设有一个中文文件:kbssoptsett_期权系统修改营业部信息4300.sql,内容不确实是不是utf-8编码,怎么保证程序能顺利解决各种情况,把文件名与文件内容展示到前端。

在django整个项目中,默认的编码都是utf-8,所以我们要做就是在把文件读入内存时,正确的解码即可,剩下的django都会帮我们搞掂。
对于文件名,因为带中文,我们直接使用:

# 这样就可以把文件名正常读入内存,
file_name = file_name.decode("gb2312")

而对于文件内容,我们首先需要判断文件的编码格式是什么,如果是utf-8,那如果使用decode(“gb2312”),就会报错,而如果是gb2312,不进行decode(),到时内容也无法解析,(gb2312基本都可以解析中文),所以完整的是:

with open(sql_file, "r") as f:
	# 先读取文件内容
	sql_file_content = "".join(f.readlines())
	# 只要不是 utf-8编码,一率用 gb2312 解码
	if chardet.detect(sql_file_content)["encoding"] != "utf-8":
		sql_file_content = sql_file_content.decode("gb2312")

前端最终效果图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值