我使用django_countries
模块的国家列表,问题是有几个国家的特殊字符,如'Åland Islands'
和'Saint Barthélemy'
。
我调用这个方法来获取国家名称:
country_label = fields.Country(form.cleaned_data.get('country')[0:2]).name
我知道country_label是django utils的懒惰翻译代理对象,但它没有给出正确的名称,而不是给'Ã…land Islands'
。对此有什么建议吗?
Django使用代码点存储unicode
字符串,并将字符串标识为unicode以供进一步处理。UTF-8使用四个8位字节编码,所以Django使用的unicode
字符串需要在某个时候从代码点表示法解码或解释为UTF-8表示法。在Åland Islands的情况下,似乎发生的事情是它采用UTF-8字节编码并将其解释为代码点以转换字符串。
django_countries返回的字符串很可能是u'xc5land Islands'
,其中xc5
是Å的UTF代码点表示法。在UTF-8字节表示法中,xc5
变成xc3x85
,其中xc3
和x85
每个数字都是一个8位字节。看到的:http://www.ltg.ed.ac.uk/理查德/utf - 8. cgi ?输入= xc5&模式=十六进制
或者您可以使用country_label = fields.Country(form.cleaned_data.get('country')[0:2]).name.encode('utf-8')从u'xc5land Islands'
转到'xc3x85land Islands'
如果你取每个字节并使用它们作为代码点,你会看到它会给你这些字符:Ã…
参见:http://www.ltg.ed.ac.uk/~理查德/utf - 8. - cgi ?输入= xc3&模式=十六进制和http://www.ltg.ed.ac.uk/~理查德/utf - 8. - cgi ?输入= x85&模式=十六进制
查看使用这些字符的html标记的代码片段。
<div id="test">Ã…Å</div>
所以我猜你有2种不同的编码在你的应用程序。从u'xc5land Islands'
到u'xc3x85land Islands'
的一种方法是在utf-8环境中编码为utf-8,将u'xc5'
转换为'xc3x85'
,然后从iso-8859
解码为unicode
,从而得到u'xc3x85land Islands'
。但由于它不在您提供的代码中,我猜它发生在您设置country_label
和输出未正确显示的时刻之间。要么因为编码设置而自动,要么通过某个地方的显式赋值。
:
为你的应用程序设置编码,在你的py文件的顶部添加# -*- coding: utf-8 -*-
,在你的模板中添加<meta charset="UTF-8">
。并从django.utils.functional中获取unicode字符串。代理对象,可以调用unicode()
。像这样:
country_label = unicode(fields.Country(form.cleaned_data.get('country')[0:2]).name)
第二个编辑:
找出问题所在的另一种方法是使用force_bytes
(https://docs.djangoproject.com/en/1.8/ref/utils/#module-django.utils.encoding)像这样:
from django.utils.encoding import force_bytes
country_label = fields.Country(form.cleaned_data.get('country')[0:2]).name
forced_country_label = force_bytes(country_label, encoding='utf-8', strings_only=False, errors='strict')
但是既然你已经尝试了很多转换都没有成功,也许问题更复杂。你能分享你的django_countries
, Python
版本和你的django应用语言设置吗?您还可以直接查看djano_countries
包(应该在python目录中),找到文件data.py并打开它,看看它是什么样子。可能数据本身已经损坏
try:
from __future__ import unicode_literals #Place as first import.
AND/OR
country_label = fields.Country(form.cleaned_data.get('country')[0:2]).name.encode('latin1').decode('utf8')
就在这周,我遇到了一个类似的编码错误。我认为这个问题是因为机器编码与Python上的编码不同。尝试将此添加到.bashrc
或.zshrc
。
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8