Кодировка стран Джанго не дает правильное название
Я использую django_countries
модуль для списка стран, проблема в том, что есть пара стран со специальными символами, такими как 'Åland Islands'
а также 'Saint Barthélemy'
,
Я вызываю этот метод, чтобы получить название страны:
country_label = fields.Country(form.cleaned_data.get('country')[0:2]).name
Я знаю, что country_label - это ленивый переведенный прокси-объект утилит django, но он не дает правильное имя, а дает 'Ã…land Islands'
, какие-либо предложения для этого, пожалуйста?
3 ответа
Джанго магазины unicode
строка с использованием кодовых точек и идентифицирует строку как юникод для дальнейшей обработки.
UTF-8 использует четыре 8-битных байта кодирования, поэтому unicode
Строка, которая используется Django, должна быть декодирована или интерпретирована от записи кодовой точки до ее записи 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-нотацией этих символов.
<div id="test">Ã…Å</div>
Я предполагаю, что в вашем приложении есть 2 разных кодировки. Один из способов получить от u'\xc5land Islands'
в u'\xc3\x85land Islands'
будет в кодировке UTF-8 в UTF-8, который будет конвертировать u'\xc5'
в '\xc3\x85'
а затем декодировать в unicode
от iso-8859
который дал бы u'\xc3\x85land Islands'
, Но поскольку этого нет в коде, который вы предоставляете, я предполагаю, что это происходит где-то между моментом, когда вы установили country_label
и в тот момент, когда ваш вывод не отображается должным образом. Либо автоматически из-за настроек кодировки, либо через явное назначение куда-то.
Первое редактирование:
Чтобы установить кодировку для вашего приложения, добавьте # -*- coding: utf-8 -*-
в верхней части вашего файла Py и <meta charset="UTF-8">
в вашем шаблоне. И чтобы получить строку юникода из django.utils.functional. прокси- объект, который вы можете вызвать 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/)
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 и откройте его, чтобы посмотреть, как он выглядит. Возможно, сами данные повреждены.
Пытаться:
from __future__ import unicode_literals #Place as first import.
И / ИЛИ
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
Затем откройте новый терминал и снова запустите приложение Django.