Django 使用代码点存储unicode 字符串,并将字符串标识为 unicode 以供进一步处理。
UTF-8 使用四个 8 位字节编码,因此 Django 使用的 unicode 字符串需要在某些时候从代码点表示法解码或解释为其 UTF-8 表示法。
在奥兰群岛的情况下,似乎正在发生的事情是它采用 UTF-8 字节编码并将其解释为代码点来转换字符串。
django_countries 返回的字符串很可能是u'\xc5land Islands',其中\xc5 是Å 的UTF 代码点符号。在 UTF-8 字节表示法中,\xc5 变为 \xc3\x85,其中每个数字 \xc3 和 \x85 是一个 8 位字节。看:
http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=xc5&mode=hex
或者您可以使用 country_label = fields.Country(form.cleaned_data.get('country')[0:2]).name.encode('utf-8') 从 u'\xc5land Islands' 转到 '\xc3\x85land Islands'
如果您将每个字节用作代码点,您会看到它会为您提供以下字符:Ã…
见:http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=xc3&mode=hex
还有:http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=x85&mode=hex
查看带有这些字符的 html 符号的代码 sn-p。
<div id="test">&#xC3;&#x85;&#xC5;</div>
所以我猜你的应用程序中有 2 种不同的编码。从u'\xc5land Islands' 到u'\xc3\x85land Islands' 的一种方法是在utf-8 环境中编码为UTF-8,它将u'\xc5' 转换为'\xc3\x85',然后从iso-8859 解码为unicode,这将给出u'\xc3\x85land Islands'。但由于它不在您提供的代码中,我猜它发生在您设置 country_label 和您的输出未正确显示之间的某处。由于编码设置而自动进行,或者通过某处的显式分配。
首次编辑:
要为您的应用设置编码,请在 py 文件顶部添加 # -*- coding: utf-8 -*- 并在模板中添加 <meta charset="UTF-8">。
要从 django.utils.functional.proxy 对象中获取 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 并打开它看看它的样子。可能数据本身已损坏。