UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0xc4 в позиции 1: порядковый номер не входит в диапазон(128)

Итак, как следует из названия вопроса, у меня проблема с кодированием/декодированием строк.

Я использую: python 2.7 | django 1.11 | jinja2 2.8

В принципе, я получаю некоторые данные из базы данных, сериализую их, устанавливаю на них кэш, затем получаю кэш, десериализую его и вывожу в шаблон.

< < <
active_agents = User.region_objects.get_active_agents()
agents_by_commission_last_month = active_agents.values(....
                                                          "first_name", "last_name").order_by(
        '-total_paid_transaction_value_last_month')
Пример сериализованного словаря выглядит так (у меня их 10):

Затем, когда я устанавливаю кэш, я делаю это следующим образом:

for key, value in context.items():
   ......
   value = json.dumps(list(value), default=str, ensure_ascii=False).encode('utf-8')

, где value - список словарей, возвращаемый .values() из вышеупомянутого кода, а key - region_agents_by_commission_last_month (как переменная из предыдущего кода)

Теперь мне нужно получить кэш. Поэтому я выполняю тот же процесс, но в обратном направлении.

serialized_keys = ['agencies_by_commission_last_month',
                       'region_agents_by_commission_last_month', 'region_agents_by_commission_last_12_months',
                       'region_agents_by_commission_last_30_days',
                       'agencies_by_commission_last_year',
                       'agencies_by_commission_last_12_months',
                       'agencies_by_commission_last_30_days',
                       'region_agents_by_commission_last_year',
                       'agency',
                       'for_agent']
    context = {}

    for key, value in region_ranking_cache.items():
        if key in serialized_keys:
            objects = json.loads(value, object_hook=_decode_dict)
            for serilized_dict in objects:
                ....
                 d['full_name'] = d['first_name'] + " " + d['last_name']
                 full_name = d['full_name'].decode('utf-8').encode('utf-8')
                 d['full_name'] = full_name
                 print(d['full_name'])
                ....

где _decode_dict для object_hook выглядит следующим образом:

Результат печати: Cătălin Pintea , что нормально. Но в словаре я отображаю: 'full_name': 'C\xc4\x83t\xc4\x83lin Pintea',

def _decode_list(data):
    rv = []
    for item in data:
        if isinstance(item, unicode):
            item = item.encode('utf-8')
        elif isinstance(item, list):
            item = _decode_list(item)
        elif isinstance(item, dict):
            item = _decode_dict(item)
        rv.append(item)
    return rv


def _decode_dict(data):
    rv = {}
    for key, value in data.items():
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        elif isinstance(value, list):
            value = _decode_list(value)
        elif isinstance(value, dict):
            value = _decode_dict(value)
        rv[key] = value
    return rv

В основном, я использую эту функцию object hook для того, чтобы кодировать() в utf-8 все ключи и значения, когда json.loads.

Вот как я избежал появления этой ошибки в views.py.

Ошибка

Где-то в шаблоне я использую:

<td>{{ agent.full_name }}</td>

А agent.full_name берется из : 'full_name': 'C\xc4\x83t\xc4\x83lin Pintea',

И именно отсюда возникает ошибка. Я пробовал другие вещи, но я предполагаю, что это ограничение python 2.7. Обычно я использую python 3.9, но для этого проекта мне приходится использовать 2.7. Я пробовал другие ответы здесь, но ничего действительно не помогло.

Может ли кто-нибудь помочь мне правильно сериализовать этот словарь и как я могу избежать этого беспорядка?

Надеюсь, я ясно выразился.

Всем хорошего дня!

Итак, мне удалось решить свою проблему.

  1. Я понял, что active_agents.values(...."first_name", "last_name").order_by('-total_paid_transaction_value_last_month') извлекал словарь, в котором ключ и значения уже были в юникоде (из-за того, как он был настроен в models.py, django 1.11 и python2.7. Таким образом, процесс сериализации прошел нормально. Действительно, конечный результат, который отправлялся в шаблон, выглядел как ’C\xc4\x83t\xc4\x83lin'. Ошибка возникла из-за /xc4/.
  2. .
  3. Для того чтобы исправить ее в шаблоне, я сделал следующее: {{ agent.full_name.decode("utf-8") }}, что дало мне правильный результат: Cătălin Pintea

Спасибо @BoarGules. Это правда, что d['last_name'] и d['first_name'] были в юникоде. Поэтому, когда я выполнял конкатенацию, мне пришлось добавить u" ".

Вернуться на верх