2015-06-04 3 views
14

Я использую модуль для списка стран, но проблема в том, что есть несколько стран со специальными символами, такими как 'Åland Islands' и 'Saint Barthélemy'.django countries encoding не дает правильного имени

Я называю этот метод, чтобы получить название страны:

country_label = fields.Country(form.cleaned_data.get('country')[0:2]).name 

Я знаю, что country_label ленив переводится прокси объект Джанго утилитами, но это не дает правильное имя, а это дает 'Ã…land Islands'. любые предложения для этого, пожалуйста?

ответ

0

попробовать:

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') 
+0

Оба решения не работают. Второй вариант дает исключение. Во втором варианте я получаю 'UnicodeDecodeError UnicodeDecodeError: 'utf8' кодек не может декодировать байт 0xc5 в положении 0: неверная продолжение байт ' – Maverick

4

Django хранит 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 ('страна') [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">&#xC3;&#x85;&#xC5;</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 и момент, когда ваш вывод отображается неправильно. Либо автоматически из-за настроек кодирования, либо через явное назначение.

FIRST EDIT:

Чтобы установить кодировку для вас приложения, добавить # -*- coding: utf-8 -*- в верхней части файла и р <meta charset="UTF-8"> в вашем шаблоне. И получить строку unicode из django.utils.functional. прокси объект можно позвонить unicode(). Как это:

country_label = unicode(fields.Country(form.cleaned_data.get('country')[0:2]).name) 

ВТОРОЙ EDIT:

Еще один способ выяснить, где проблема будет использовать 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 и открыть его, чтобы посмотреть, как он выглядит. Возможно, сами данные повреждены.

+0

Я использовал 'country_label = fields.Country (form.cleaned_data.get ('страна') [0: 2]). Name.encode ('utf-8') 'в коде, но все же он отображается как' Ã ... land'. Я использую метод render для получения шаблона. – Maverick

+0

См. Редактирование, я предполагаю, что country_label переходит прямо в контекст и не сохраняется в db перед тем, как быть рендерингом? –

+0

@mad_programmer Что произойдет, если вы передадите аргумент кодировки в 'unicode()', например: 'unicode (fields.Country (...). Name, 'UTF-8')'? – xyres

0

Только на этой неделе я столкнулся с аналогичной ошибкой кодирования. Я считаю, что проблема в том, что машинное кодирование отличается от машинного на Python. Попробуйте добавить это к .bashrc или .zshrc.

export LC_ALL=en_US.UTF-8 
export LANG=en_US.UTF-8 

Затем откройте новый терминал и запустите приложение Django.

Смежные вопросы