2012-02-09 23 views
6

Mi pregunta es similar a la reportada here, pero la solución propuesta no funciona para mí. Estoy intentando subir un archivo llamado 'Testaråäö.txt' a través de la aplicación de administración de Django.UnicodeEncodeError al cargar archivos en el administrador de Django

Estoy ejecutando Django 1.3.1 con Gunicorn 0.13.4 y Nginx 0.7.6.7 en un servidor Debian 6. La base de datos es PostgreSQL 8.4.9. Otros datos Unicode se guardan en la base de datos sin problemas, así que supongo que el problema debe ser con el sistema de archivos de alguna manera.

He configurado

http { 
    charset utf-8; 
} 

en mi nginx.conf. LC_ALL y LANG están configurados en 'sv_SE.UTF-8'. Ejecutar 'locale' lo verifica. Incluso intenté configurar LC_ALL y LANG en mi script nginx init solo para asegurarme de que la configuración regional esté configurada correctamente.

Aquí está el rastreo:

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) 

ACTUALIZACIÓN: Intenté funcionar Gunicorn con la depuración activada, y las cargas de archivos sin ningún problema en absoluto. Supongo que esto debe significar que el problema es con Nginx. Sin embargo, todavía me gana donde mirar. Aquí están las cabeceras de respuesta primas de Gunicorn y Nginx, si tiene algún sentido:

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

¿Alguna vez una solución para esto? ¿Cómo estás iniciando gunicornio? – ashwoods

+0

Lo siento, no. Le dije a mi cliente que simplemente evitara usar caracteres Unicode hasta que pudiera encontrar una solución (que cada vez parece más como migrar a un servidor diferente). Estoy usando Supervisor para comenzar con Gunicorn. –

+0

Esto también nos sucede a nosotros. La misma configuración: NginX, Supervisor, Gunicorn ejecuta la aplicación Django.He perdido dos horas tratando de arreglarlo, intenté todas las recomendaciones en Internet sin suerte. Con suerte, alguien encontrará la manera de hacer que esto funcione eventualmente. – xaralis

Respuesta

6

parece que es un problema común que el servicio que ejecuta el servicio django, ya sea apache, gunicorn + supervisor, daemontools, etc ... no siempre utiliza las variables de entorno correctas.

En este caso, gunicorn se inicia por el supervisor, así que hay que decirle explícitamente supervisor para utilizar UTF-8 utilizando la opción de entorno:

environment=LANG=en_US.UTF-8, LC_ALL=en_US.UTF-8, LC_LANG=en_US.UTF-8 
+2

Parece que en Supervisor 3.0a8 (la versión proporcionada en Debian Squeeze) la opción 'environment' debe especificarse globalmente en la sección' [supervisord] 'del archivo de configuración. No se reconoce en las secciones '[program: *]'. – akaihola

+0

akaihola gracias, pasé las últimas 3 horas buscando eso ..... – migajek

+0

gracias, esto funcionó muy bien. – Marco

1

que tenía el mismo problema con genericpath.py dando un UnicodeEncodeError al intentar cargar un nombre de archivo con caracteres que no sean ASCII.

Estaba usando nginx, uwsgi y django con python 2.7.

Todo estaba funcionando bien a nivel local, pero no en el servidor

Éstos son los pasos que di:

  1. añaden a/etc/nginx/nginx.conf (no solucionar el problema)

    http { 
        charset utf-8; 
    } 
    
  2. añadí esta línea a etc/default/locale (no solucionar el problema)

    LANGUAGE="en_US.UTF-8" 
    
  3. he seguido las instrucciones aquí enumerados bajo el epígrafe 'éxito' https://code.djangoproject.com/wiki/ExpectedTestFailures (no solucionar el problema)

    aptitude install language-pack-en-base 
    
  4. encontrado a través de este billete https://code.djangoproject.com/ticket/17816 que sugería probar una vista en el servidor a lo que sucedía con la información de localización vista

Django

import locale 

def locales(request): 
    """Display the locales""" 
    locales = "Current locale: %s %s -- Default locale: %s %s" % (
     locale.getlocale() + locale.getdefaultlocale()) 
    default_encoding = sys.getdefaultencoding() 
    file_system_encoding = sys.getfilesystemencoding() 

    context = { 
     'locales': locales, 
     'default_encoding': default_encoding, 
     'file_system_encoding': file_system_encoding, # affects file uploads 
    } 
    return render(request, 'testing/locales.html', context) 

Django plantilla

<h2>Locales</h2> 
<p>{{ locales }}</p> 

<h2>Default Encoding</h2> 
<p>{{ default_encoding }}</p> 

<h2>File System Encoding</h2> 
<p>{{ file_system_encoding }}</p> 

Para mí, el problema era que No tenía locale ni locale predeterminada en mi servidor Ubuntu (aunque sí los tenía en mi máquina de desarrollo OSX local) y luego archivos con archivo no ASCII Los nombres/rutas no se cargarán correctamente con python generando un UnicodeEncodeError, pero solo en el servidor de producción.

Solución

he añadido a este tanto mi mi sitio de administración de archivos de configuración uwsgi por ejemplo, sitio y/Etc/uwsgi-emperador/vasallos/mi-site-config-ini archivo

env = LANG=en_US.utf8 

actualización

Después de trasladarse a ventana acoplable empecé a recibir el mismo error de nuevo. Después de investigarlo más a fondo, me di cuenta de que en la instancia de django de uwsgi import sys; sys.getfilesystemencoding() o {{ file_system_encoding }} anterior devolvía ANSI_X3.4-1968; sin embargo, si comenzaba mi propia instancia de python y ejecutaba import sys; sys.getfilesystemencoding(), obtenía UTF-8. El formato ANSI_X3.4-1968 es lo que está arrojando el UnicodeEncodeError.

Así, además de la solución uwsgi mencionados en esta respuesta anterior, también tuvo que añadir esto a mi Django dockerfile

ENV LANG en_US.UTF-8 
RUN apt-get update && install -y locales && \ 
    sed -i -e "s/# $LANG.*/$LANG UTF-8/" /etc/locale.gen && \ 
    locale-gen --purge &&\ 
    update-locale LANG=$LANG 

O si no está utilizando ventana acoplable que sólo puede funcionar esto en la cáscara

$ export LANG=en_US.UTF-8 

A continuación, ejecute el comando EJECUTAR arriba (pero sin RUN).

Referencias:

http://stackoverflow.com/a/37246853/3003438 
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/uwsgi/ 
+0

Esta es una gran respuesta, con una guía de diagnóstico paso a paso. No sé por qué tiene tan poco votos positivos. Tenga en cuenta que en el caso de Ubuntu necesita un paquete de idioma para su idioma. Entonces, si establece el env de 'LANG' para decir 'español', debe agregar' aptitude install language-pack-es-base'. Similar para todos los demás idiomas. –

Cuestiones relacionadas