2010-09-15 30 views
36

Al cargar archivos con caracteres no ASCII consigo UnicodeEncodeError:UnicodeEncodeError: códec 'ascii' no puede codificar caracteres

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) 

Ver full stack trace.

Ejecuto Django 1.2 con MySQL y nginx y FastCGI.

Este es un problema que se soluciona de acuerdo con Django Trac database, pero todavía tengo el problema. Cualquier sugerencia sobre cómo solucionarlo es bienvenida.

EDIT: Este es mi campo de imagen:

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

¿Puedes dar la definición del modelo/campo también? En particular, estoy interesado en ver la definición 'upload_to'. –

+0

Actualizado con la definición de upload_to. – vorpyg

+2

Para cualquiera que todavía aterrice aquí revise el último comentario del ticket Django por akaihola, él dice: "Debian ejecuta Apache con la configuración LANG = C por defecto, lo que rompe la carga de archivos con caracteres especiales en sus nombres al menos cuando se ejecuta con mod_wsgi. La configuración regional de UTF-8 en/etc/apache2/envvars debería resolver el problema "El ticket: http://code.djangoproject.com/ticket/6009 –

Respuesta

12

Después de investigar esto un poco más descubrí que no había puesto el juego de caracteres en mi principal Nginx fichero de configuración:

http { 
    charset utf-8; 
} 

Mediante la adición de lo anterior, el problema desapareció y creo que esta es la forma correcta de manejar este problema.

+4

Esto solo podría funcionar si nginx está ejecutando directamente el código de back-end. Asumiendo que es un proxy para algo como gunicorn o uwsgi, tendrás que configurar el entorno del servidor wsgi para usar UTF-8. Agregar esto a su configuración de Nginx no duele, pero probablemente no resolverá su problema. – amjoconn

+0

Como ya mencioné en @amjoconn, en mi caso el problema se resolvió agregando "env = LC_ALL = ru_RU.UTF-8" a mi archivo uwsgi-config –

4

Es difícil de decir sin ver un poco más de código pero parece estar relacionada con esta pregunta: UnicodeDecodeError on attempt to save file through django default filebased backend.

Mirando a través de la entrada de Django mencionado, parecería que debe seguir algo similar a la documentación de implementación en "Si se obtiene un UnicodeEncodeError":
https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror

(Sé que esto es para Apache/mod_python pero mi conjetura sería que es la misma edición de la raíz de la codificación del sistema de archivos no ser UTF-8 y no hay una solución similar usando nginx)

EDIT: de lo que puedo decir de este módulo nginx sería la solución equivalente: http://wiki.nginx.org/NginxHttpCharsetModule

+0

Sospecho que podría tener algo que ver con esto. Intenté agregar una u al frente de la cadena, como se describe aquí: http://stackoverflow.com/questions/2457087/unicodedecodeerror-on-attempt-to-save-file-through-django-default-filebased-backe/2458200 # 2458200 sin suerte. ¿Tienes un enlace al arreglo nginx? – vorpyg

+1

Ver mi última edición para el enlace. –

+0

Gracias, todavía no funciona, sin embargo. Intenté configurar la configuración regional, como se indica en los documentos de Django, y también intenté agregar el conjunto de caracteres utf8 a mi configuración de nginx.Tal vez solo tenga que volver a escribir el método de guardar para cambiar el nombre del archivo primero ... – vorpyg

24

En situaciones en las que debe mostrar una cadena Unicode en un lugar que solo acepta Ascii (como la consola o como una ruta de acceso) debe decirle a Python que desea que reemplace el mejor esfuerzo de los caracteres no ASCI. se impide

>> 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' 

problemas de codificación en el administrador de la entrega cautelosa de Django plantillas, pero si alguna vez ha añadido columnas personalizadas y olvidado para convertir los valores a ASCII, o anulan la método str para un modelo y olvídate de hacer esto, obtendrás el mismo error, evitando la representación de la plantilla.

Si esta cadena se guarda en su (UTF-8 con suerte) de base de datos no habría ningún problema, parece que está intentando cargar un archivo que utiliza el título de una entidad que tiene un carácter no ASCII.

+0

¡Gracias! Me encontré con esta respuesta después de la búsqueda infructuosa de una pregunta simple: ¿cómo puedo enviar un correo electrónico con caracteres no latinos en Python? Tu solución funciona! – skanatek

+0

imprimir unicode (exc) .encode ('ascii', 'ignorar') –

12

Espero que esto ayude. En mi caso, estoy ejecutando django a través de daemontools.

Configuración

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

en escritura antes de efectuar el manage.py resuelto el problema con archivos de nombre de archivo

4

Como dije antes, está relacionado con la configuración regional.Por ejemplo, si utiliza gunicorn para servir su django application, puede tener un script init.d (o, como yo, un script de runit), donde puede establecer la configuración regional.

Para resolver UnicodeEncodeError con la carga de archivos, ponga algo como export LC_ALL=en_US.UTF8 en el script que ejecuta su aplicación.

Por ejemplo, este es el mío (usando gunicorn y runit):

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

Además, se puede comprobar la configuración regional en su plantilla, el uso de este en su punto de vista:

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

Y justo disply {{loc}} - {{loc_def}} en su plantilla.

¡Tendrás más información sobre la configuración de tu configuración regional! Eso fue muy útil para mí.

37

Para cualquier persona que encuentre este problema al ejecutar Django con Supervisor, la solución es agregar, p. el siguiente a la sección supervisord de configuración del supervisor:

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

Esto resolvió el problema para mí en Supervisor 3.0a8 se ejecuta en Debian Squeeze.

+5

Asegúrese de que /etc/init.d/supervisor se detenga y/etc /init.d/supervisor comienza para que el cambio surta efecto. Solo reiniciar no funcionará. – amjoconn

+0

Si obtiene este error _Presupuesto inesperado de pares clave/valor_, deberá citar los valores. p.ej. entorno = LANG = 'en_US.utf8'. https://lists.supervisord.org/pipermail/supervisor-users/2010-March/000539.html – amos

+1

Puede forzar la lectura de los archivos de configuración con 'supervisorctl reread' y' supervisorctl restart myservice' en lugar de detener e iniciar todo el daemon . – Udi

3

usando Python 2.7.8 y Django 1.7, he resuelto mi problema con la importación de:

from __future__ import unicode_literals 

y el uso de force_text():

from django.utils.encoding import force_text 
4

Otra opción útil que evita reescribir el código es cambiar la codificación predeterminada para python.

Si está utilizando virtualenv puede cambiar (o crear si no existe) env/lib/python2.7/sitecustomize.py y añadir:

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

o, si se encuentra en un sistema de producción, se puede hacer lo mismo con /usr/lib/python2.7/sitecustomize.py

9

La respuesta de akaihola fue útil. Para los que corren aplicaciones Django con uWSGI logró a través de script advenedizo, sólo tiene que añadir estas líneas a su /etc/init/yourapp.conf

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

Se resolvió el problema para mí.

+2

¡Gracias! ¡Esta es la forma en que resolvió mi problema! 'env LANG =" en_US.UTF-8 " env LC_ALL =" en_US.UTF-8 " env LC_LANG =" en_US.UTF-8 "'. Tenga en cuenta que es 'env' no' export'. Esta es la sintaxis para usar bajo el script System V (/etc/init/xxx.conf). Este error me ha costado horas. – moonkey

1

Sólo sobre la base de las respuestas de este hilo y otros ...

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

Estaba usando nginx, uwsgi y django con python 2.7.

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

Estos son los pasos que di 1. añaden a /etc/nginx/nginx.conf (no solucionar el problema)

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

LANGUAGE = "en_US.UTF-8"

  1. He seguido las instrucciones aquí enumerados bajo el título 'éxito' https://code.djangoproject.com/wiki/ExpectedTestFailures (no solucionar el problema)

    aptitude install language-pack-en-base 
    
  2. encontrado a través de este billete https://code.djangoproject.com/ticket/17816 cuales sugirió probar una vista en el servidor para lo que estaba ocurriendo con la información de localización

en su opinión

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

En su plantilla

{{ locales }} 

Para mí, el problema era que no tenía ningún local ni regional predeterminada en mi servidor de Ubuntu (aunque los tuviera en mi máquina dev OSX local) y luego los archivos con rutas/nombres de archivo que no sean ASCII 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 
+0

Mi solución actualizada aquí: http://stackoverflow.com/a/31001281/3003438 –

0

Ninguna de las respuestas trabajó para mí (usando Apache en Ubuntu con Django 1.10); Elegí eliminar los acentos del nombre de archivo (normalizar) como se muestra a continuación:

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) 
Cuestiones relacionadas