Ответ 1
После изучения этого еще я узнал, что я не установил кодировку в своем основном файле конфигурации Nginx:
http {
charset utf-8;
}
Добавив вышеизложенное, проблема исчезла, и я думаю, что это правильный способ решения этой проблемы.
При загрузке файлов с не-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)
После изучения этого еще я узнал, что я не установил кодировку в своем основном файле конфигурации Nginx:
http {
charset utf-8;
}
Добавив вышеизложенное, проблема исчезла, и я думаю, что это правильный способ решения этой проблемы.
Для тех, кто сталкивается с этой проблемой при запуске 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.
В ситуациях, когда вы должны отображать строку юникода в месте, которое принимает только 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.
Надеюсь, это поможет. В моем случае я запускаю django через daemontools.
Настройка
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'
в run script перед выполнением manage.py разрешена проблема с uploads filename
Ответ 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"
Он решил проблему для меня.
Трудно сказать, не увидев немного больше кода, но похоже, что это связано с этим вопросом: 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
Как уже говорилось, это связано с локалью. Например, если вы используете 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}}
в своем шаблоне.
У вас будет больше информации о ваших настройках языка! Это было очень полезно для меня.
Еще одна полезная опция, которая позволяет избежать перезаписи кода, заключается в изменении кодировки по умолчанию для python.
Если вы используете virtualenv, вы можете изменить (или создать, если не существует) env/lib/python2.7/sitecustomize.py
и добавить:
import sys
sys.setdefaultencoding('utf-8')
или, если вы находитесь в производственной системе, вы можете сделать то же самое с /usr/lib/python2.7/sitecustomize.py
Если вы используете django и python 2.7, это исправляет это для меня:
@python_2_unicode_compatible
class Utente(models.Model):
см. https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.encoding.python_2_unicode_compatible
Используя python 2.7.8 и Django 1.7, я решил свою проблему, импортировав:
from __future__ import unicode_literals
и используя force_text()
:
from django.utils.encoding import force_text
Просто основываясь на ответах из этой темы и других...
У меня была такая же проблема с genericpath.py, которая давала UnicodeEncodeError при попытке загрузить имя файла с несимвольными символами.
Я использовал nginx, uwsgi и django с python 2.7.
Все работает нормально локально, но не на сервере
Вот шаги, которые я предпринял 1. добавлен в /etc/nginx/nginx.conf(не удалось устранить проблему)
http {
charset utf-8;
}
ЯЗЫК = "en_US.UTF-8"
Я выполнил инструкции, перечисленные в разделе "Успех", https://code.djangoproject.com/wiki/ExpectedTestFailures (не удалось устранить проблему)
aptitude install language-pack-en-base
Найдено через этот билет 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
Ни один из ответов не работал у меня (используя 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)