Заметка: Я задал этот вопрос на StackOverflow, но понимаю, что это более подходящее место, чтобы задать такой вопрос.
Я пытаюсь загрузить файл под названием Testaråäö.txt через приложение администратора Django.
Я запускаю Django 1.3.1 с Gunicorn 0.13.4 и Nginx 0.7.6.7 на сервере Debian 6. База данных - PostgreSQL 8.4.9. Другие данные Unicode сохраняются в базе данных без проблем, поэтому я предполагаю, что проблема должна быть каким-то образом связана с файловой системой.
Я установил
http {
charset utf-8;
}
в моем nginx.conf. LC_ALL и LANG установлен на 'sv_SE.UTF-8'. Запуск "locale" подтверждает это. Я даже попытался установить LC_ALL и LANG в моем сценарии инициализации nginx, чтобы убедиться, что языковой стандарт установлен правильно.
Вот трассировка:
Traceback (most recent call last):
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 307, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 93, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/views/decorators/cache.py", line 79, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/sites.py", line 197, in inner
return view(request, *args, **kwargs)
File "/srv/django/letebo/app/cms/admin.py", line 81, in change_view
return super(PageAdmin, self).change_view(request, obj_id)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 28, in _wrapper
return bound_func(*args, **kwargs)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 93, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 24, in bound_func
return func(self, *args2, **kwargs2)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/transaction.py", line 217, in inner
res = func(*args, **kwargs)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 985, in change_view
self.save_formset(request, form, formset, change=True)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 677, in save_formset
formset.save()
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 482, in save
return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 613, in save_new_objects
self.new_objects.append(self.save_new(form, commit=commit))
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 717, in save_new
obj.save()
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 460, in save
self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 504, in save_base
self.save_base(cls=parent, origin=org, using=using)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 543, in save_base
for f in meta.local_fields if not isinstance(f, AutoField)]
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/fields/files.py", line 255, in pre_save
file.save(file.name, file, save=False)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/fields/files.py", line 92, in save
self.name = self.storage.save(name, content)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 48, in save
name = self.get_available_name(name)
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 74, in get_available_name
while self.exists(name):
File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 218, in exists
return os.path.exists(self.path(name))
File "/srv/.virtualenvs/letebo/lib/python2.6/genericpath.py", line 18, in exists
st = os.stat(path)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 52-54: ordinal not in range(128)
Я попробовал запустить Gunicorn с включенной отладкой, и файл загружается без каких-либо проблем. Я полагаю, это должно означать, что проблема в Nginx. Хотя мне все еще непонятно, куда смотреть. Вот заголовки необработанных ответов от Gunicorn и Nginx, если это имеет смысл:
Gunicorn:
HTTP/1.1 302 FOUND
Server: gunicorn/0.13.4
Date: Thu, 09 Feb 2012 14:50:27 GMT
Connection: close
Transfer-Encoding: chunked
Expires: Thu, 09 Feb 2012 14:50:27 GMT
Vary: Cookie
Last-Modified: Thu, 09 Feb 2012 14:50:27 GMT
Location: http://my-server.se:8000/admin/cms/page/15/
Cache-Control: max-age=0
Content-Type: text/html; charset=utf-8
Set-Cookie: messages="yada yada yada"; Path=/
Nginx:
HTTP/1.1 500 INTERNAL SERVER ERROR
Server: nginx/0.7.67
Date: Thu, 09 Feb 2012 14:50:57 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: close
Vary: Cookie
500
ОБНОВИТЬ: Обе locale.getpreferredencoding()
и sys.getfilesystemencoding()
выходы 'UTF-8'
. locale.getdefaultlocale()
выходы ('sv_SE', 'UTF8')
. Мне это кажется правильным, поэтому я до сих пор не понимаю, почему я продолжаю получать эти ошибки.
У меня была такая же проблема с genericpath.py, выдающей UnicodeEncodeError при попытке загрузить имя файла с символами, отличными от ASCII.
Я использовал nginx, uwsgi и django с python 2.7.
Все работало нормально локально, но не на сервере
Вот шаги, которые я предпринял: 1. добавлен в /etc/nginx/nginx.conf (не устранил проблему)
http {
charset utf-8;
}
LANGUAGE = "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, используя mod_wsgi, это можно решить, добавив lang
и locale
варианты для WSGIDaemonProcess
в файле конфигурации вашего сайта.
Обычно должно быть установлено на en_US.UTF-8
согласно документам:
https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIDaemonProcess.html
Вот так:
lang=en_US.UTF-8 locale=en_US.UTF-8
Например:
WSGIDaemonProcess processName python-home=/path/to/venv python-path=/path/to/mydjangoproject lang=en_US.UTF-8 locale=en_US.UTF-8
После добавления этих параметров перезапустите Apache, и все будет в порядке.
У меня была такая же проблема, и я нашел исправления для своих случаев (я запускаю Ubuntu).
Я нашел здесь хорошую тему без ответа, где Карен дала некоторую полезную информацию:
https://groups.google.com/forum/?fromgroups#!topic/django-users/hwNL7i6IeIY
что привело меня к этому:
https://code.djangoproject.com/wiki/ExpectedTestFailures
Я установил недостающий языковой пакет для Ubuntu. и я запустил оболочку как root:
locale-gen en_US.UTF-8
и теперь он работает.
Похоже, что на низкоуровневых уровнях Python что-то вызывает Glibc, которому для правильной работы нужны некоторые скомпилированные файлы, сгенерированные locale-gen.
Я заглянул в http://packages.debian.org а в Debian нет такого пакета.
Попробуйте запустить следующее и перезапустите демон перед повторной попыткой:
locale-gen sv_SE.UTF-8
или, возможно, установить какие-либо специфические языковые / языковые пакеты Debian, если они есть.