Подтвердить что ты не робот

UnicodeEncodeError: кодек 'ascii' не может кодировать символ

При загрузке файлов с не-ASCII-символами я получаю UnicodeEncodeError:

Exception Type: UnicodeEncodeError at /admin/studio/newsitem/add/
Exception Value: 'ascii' codec can't encode character u'\xf8' in position 78: ordinal not in range(128)

Смотрите полную трассировку стека.

Я запускаю Django 1.2 с MySQL и nginx и FastCGI.

Это проблема, которая исправлена ​​в соответствии с базой данных Django Trac, но у меня все еще есть проблема. Любые предложения о том, как исправить, приветствуются.

EDIT: Это мое поле изображения:

image = models.ImageField(_('image'), upload_to='uploads/images', max_length=100)
4b9b3361

Ответ 1

После изучения этого еще я узнал, что я не установил кодировку в своем основном файле конфигурации Nginx:

http {
  charset  utf-8;
}

Добавив вышеизложенное, проблема исчезла, и я думаю, что это правильный способ решения этой проблемы.

Ответ 2

Для тех, кто сталкивается с этой проблемой при запуске Django с Supervisor, решение должно добавить, например. в раздел supervisord конфигурации Supervisor:

environment=LANG="en_US.utf8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8"

Это решило проблему для меня в Supervisor 3.0a8, запущенной на Debian Squeeze.

Ответ 3

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

>> problem_str = u'This is not all ascii\xf8 man'
>> safe_str = problem_str.encode('ascii', 'ignore')
>> safe_str
'This is not all ascii man'

Проблемы с кодированием предотвращаются администратором путем осторожной передачи шаблонов Django, но если вы когда-либо добавляли пользовательские столбцы и забывали преобразовать значения в ascii или переопределили метод str для модель и забудьте сделать это, вы получите ту же ошибку, предотвращая создание шаблона.

Если эта строка была сохранена в вашей (надеюсь, utf8) базе данных, проблем не было бы, похоже, вы пытаетесь загрузить файл, который использует заголовок сущности с символом не ascii.

Ответ 4

Надеюсь, это поможет. В моем случае я запускаю django через daemontools.

Настройка

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

в run script перед выполнением manage.py разрешена проблема с uploads filename

Ответ 5

Ответ akaihola был полезен. Для тех, кто запускает приложение django с помощью uWSGI, управляемое с помощью upstart script, просто добавьте эти строки в ваш /etc/init/yourapp.conf

env LANG="en_US.utf8"
env LC_ALL="en_US.UTF-8"
env LC_LANG="en_US.UTF-8"

Он решил проблему для меня.

Ответ 6

Трудно сказать, не увидев немного больше кода, но похоже, что это связано с этим вопросом: UnicodeDecodeError при попытке сохранить файл через django default filebased backend.

Просматривая упомянутый билет Django, похоже, вам следует следовать чему-то, аналогичному документам развертывания, на "Если вы получаете UnicodeEncodeError":
https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror

(Я знаю, что это для Apache/mod_python, но я предполагаю, что это будет одна и та же корневая проблема кодирования файловой системы, которая не является UTF-8, и существует аналогичное исправление при использовании nginx)

EDIT: Из того, что я могу сказать, этот модуль nginx будет эквивалентным исправлением: http://wiki.nginx.org/NginxHttpCharsetModule

Ответ 7

Как уже говорилось, это связано с локалью. Например, если вы используете gunicorn для обслуживания своего django application, у вас может быть init.d script (или, как я, runit script), где вы можете установить локаль.

Чтобы решить проблему UnicodeEncodeError с загрузкой файла, введите export LC_ALL=en_US.UTF8 в свой script, который запустит ваше приложение.

Например, это мое (используя gunicorn и runit):

#!/bin/bash
export LC_ALL=en_US.UTF8
cd /path/to/app/projectname
exec gunicorn_django -b localhost:8000 --workers=2

Кроме того, вы можете проверить свою локаль в своем шаблоне, используя это в своем представлении:

import locale
data_to_tpl = {'loc': locale.getlocale(), 'lod_def': locale.getdefaultlocale()}

И просто используйте {{loc}} - {{loc_def}} в своем шаблоне.

У вас будет больше информации о ваших настройках языка! Это было очень полезно для меня.

Ответ 8

Еще одна полезная опция, которая позволяет избежать перезаписи кода, заключается в изменении кодировки по умолчанию для python.

Если вы используете virtualenv, вы можете изменить (или создать, если не существует) env/lib/python2.7/sitecustomize.py и добавить:

import sys
sys.setdefaultencoding('utf-8')

или, если вы находитесь в производственной системе, вы можете сделать то же самое с /usr/lib/python2.7/sitecustomize.py

Ответ 10

Используя python 2.7.8 и Django 1.7, я решил свою проблему, импортировав:

from __future__ import unicode_literals

и используя force_text():

from django.utils.encoding import force_text

Ответ 11

Просто основываясь на ответах из этой темы и других...

У меня была такая же проблема с genericpath.py, которая давала UnicodeEncodeError при попытке загрузить имя файла с несимвольными символами.

Я использовал nginx, uwsgi и django с python 2.7.

Все работает нормально локально, но не на сервере

Вот шаги, которые я предпринял 1. добавлен в /etc/nginx/nginx.conf(не удалось устранить проблему)

http {
    charset utf-8;
}
  1. Я добавил эту строку в etc/default/locale (не исправил проблему)

ЯЗЫК = "en_US.UTF-8"

  1. Я выполнил инструкции, перечисленные в разделе "Успех", https://code.djangoproject.com/wiki/ExpectedTestFailures (не удалось устранить проблему)

    aptitude install language-pack-en-base
    
  2. Найдено через этот билет https://code.djangoproject.com/ticket/17816 который предложил проверить представление на сервере того, что происходило с информацией о локали.

На ваш взгляд

import locale
locales = "Current locale: %s %s -- Default locale: %s %s" % (locale.getlocale() + locale.getdefaultlocale())

В вашем шаблоне

{{ locales }}

Для меня проблема заключалась в том, что у меня не было локали и локали по умолчанию на моем сервере Ubuntu (хотя у меня их было на моей локальной машине OSX dev), тогда файлы с именами/путями без ASCII файлов будут неправильно загружаться с помощью python повышение UnicodeEncodeError, но только на рабочем сервере.

Решение

Я добавил это как на мой сайт, так и на мои файлы настроек uwsgi для администратора сайта например/etc/uwsgi-emperor/vassals/файл my-site-config-ini

env = LANG=en_US.utf8

Ответ 12

Ни один из ответов не работал у меня (используя Apache на Ubuntu с Django 1.10); Я решил удалить акценты из имени файла (нормализовать), как показано ниже:

def remove_accents(value):
    nkfd_form = unicodedata.normalize('NFKD', str(value))
    return "".join([c for c in nkfd_form if not unicodedata.combining(c)])

uploaded_file = self.cleaned_data['data']

# We need to remove accents to get rid of "UnicodeEncodeError: 'ascii' codec can't encode character" on Ubuntu
uploaded_file.name = remove_accents(uploaded_file.name)