UnicodeEncodeError: le codec 'ascii' ne peut pas encoder le caractère

lors du téléchargement de fichiers avec des caractères non-ASCII, J'obtiens 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)

See full stack trace .

je dirige Django 1.2 avec MySQL et nginx et FastCGI.

C'est un problème qui est corrigé selon la base de données de Django Trac , mais j'ai toujours le problème. Toutes les suggestions sur la façon de corriger sont les bienvenues.

EDIT: C'est mon champ image:

image = models.ImageField(_('image'), upload_to='uploads/images', max_length=100)
36
demandé sur vorpyg 2010-09-15 12:24:34

12 réponses

pour toute personne rencontrant ce problème lors de L'exécution de Django avec superviseur , la solution est d'ajouter par exemple ce qui suit à la section supervisord de la configuration du superviseur:

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

cela a résolu le problème pour moi dans le superviseur 3.0A8 tournant sur Debian Squeeze.

38
répondu akaihola 2014-04-07 08:10:37

dans les situations où vous devez afficher une chaîne unicode dans un endroit qui n'accepte que l'ascii (comme la console ou comme un chemin), vous devez dire à Python que vous voulez qu'il remplace les caractères non 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'
Les problèmes D'encodage

sont empêchés dans l'administrateur par la manipulation prudente de Django templating, mais si vous avez déjà ajouté des colonnes personnalisées et oublié de convertir les valeurs en ascii, ou si vous outrepassez la méthode str pour un model et oublier de le faire, vous obtiendrez la même erreur, empêchant le rendu de template.

si cette chaîne était sauvegardée dans votre base de données (avec un peu de chance utf8) il n'y aurait aucun problème, il semble que vous essayez de télécharger un fichier qui utilise le titre d'une entité qui a un caractère non ascii.

24
répondu Lincoln B 2010-09-16 02:26:01

J'espère que ça aidera. Dans mon cas, je dirige django à travers les daemontools.

réglage

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

dans run script avant d'exécuter manage.py résolu le problème avec uploads nom du fichier

12
répondu AlexanderYastrebov 2011-07-04 14:59:59

après une nouvelle enquête, j'ai découvert que je n'avais pas mis le charset dans mon fichier de configuration Nginx principal:

http {
  charset  utf-8;
}

en ajoutant ce qui précède, le problème a disparu et je pense que c'est la bonne façon de traiter cette question.

12
répondu vorpyg 2011-09-29 19:30:11

la réponse d'akaihola a été utile. Pour ceux qui utilisent l'application django avec uWSGI gérée par script upstart, ajoutez simplement ces lignes à votre /etc/init/yourapp.conf

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

ça a résolu le problème pour moi.

10
répondu PawelRoman 2015-02-26 12:26:50

comme dit plus haut, il est lié à locale. Par exemple , si vous utilisez gunicorn pour servir votre django application , vous pouvez avoir un script init.d (ou, comme moi, un script runit), où vous pouvez définir la locale.

pour résoudre UnicodeEncodeError avec le téléchargement de fichier, mettez quelque chose comme export LC_ALL=en_US.UTF8 dans votre script qui exécutent votre application.

par exemple, c'est à moi (en utilisant gunicorn et runit ):

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

Aussi, vous pouvez vérifier votre locale dans votre modèle, en utilisant ceci dans votre vue:

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

et juste disply {{loc}} - {{loc_def}} dans votre modèle.

vous aurez plus d'informations sur vos paramètres de localisation! Cela a été très utile pour moi.

4
répondu Exirel 2012-03-09 16:08:55

il est difficile de dire sans voir un peu plus de code, mais il semble être liée à cette question: UnicodeDecodeError sur la tentative de sauver le fichier par django par défaut filebased backend .

en regardant à travers le billet Django mentionné, il semblerait que vous devriez suivre quelque chose de similaire au déploiement docs sur "Si vous obtenez un UnicodeEncodeError":

https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror

(Je sais que C'est pour Apache/mod_python, mais je pense que c'est le même problème de base du système de fichiers encodant N'étant pas UTF-8 et qu'il y a une correction similaire en utilisant nginx)

EDIT: De ce que je peux dire ce module nginx serait le correctif équivalent: http://wiki.nginx.org/NginxHttpCharsetModule

4
répondu Mark Lavin 2017-05-23 11:54:34

une autre option utile qui évite de réécrire le code est de changer l'encodage par défaut pour python.

si vous utilisez virtualenv vous pouvez changer (ou créer si n'existe pas) env/lib/python2.7/sitecustomize.py et ajouter:

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

ou, si vous êtes dans un système de production, vous pouvez faire la même chose à /usr/lib/python2.7/sitecustomize.py

4
répondu Enric Mieza 2014-11-20 12:41:35

si vous utilisez django et python 2.7 cela me corrige:

@python_2_unicode_compatible
class Utente(models.Model):

voir https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.encoding.python_2_unicode_compatible

3
répondu max4ever 2014-05-09 13:56:02

en utilisant python 2.7.8 et Django 1.7, j'ai résolu mon problème en important:

from __future__ import unicode_literals

et en utilisant force_text() :

from django.utils.encoding import force_text
3
répondu daveoncode 2014-10-04 08:30:16

construire sur les réponses de ce fil et d'autres...

j'ai eu le même problème avec genericpath.py donner un UnicodeEncodeError en essayant de télécharger un nom de fichier avec des caractères non ASCII.

j'utilisais nginx, uwsgi et django avec python 2.7.

tout fonctionnait bien localement mais pas sur le serveur

Voici les mesures que j'ai prises 1. ajouté à /etc/nginx/nginx.conf (n'a pas de résoudre le problem)

http {
    charset utf-8;
}
  1. j'ai ajouté cette ligne à etc/default/locale (n'a pas corrigé le problème)

    LANGUAGE="en_US.UTF-8"

  2. j'ai suivi les instructions énumérées ici sous la rubrique "succès" https://code.djangoproject.com/wiki/ExpectedTestFailures (ne résout pas le problème)

    aptitude install language-pack-en-base
    
  3. Found à travers ce billet https://code.djangoproject.com/ticket/17816 qui a suggéré de tester une vue sur le serveur à ce qui se passait avec les informations locales

À votre avis

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

dans votre modèle

{{ locales }}

pour moi, le problème était que je n'avais aucune locale et aucune locale par défaut sur mon serveur Ubuntu (bien que je les ai eu sur ma machine locale de développement OSX) puis fichiers avec des noms de fichiers/chemins non ASCII, le téléchargement ne se fera pas correctement avec python soulevant une UnicodeEncodeError, mais seulement sur le serveur de production.

Solution

j'ai ajouté ceci à la fois à mon site et à mes fichiers de config admin uwsgi par exemple, /etc/uwsgi-empereur/vassaux/mon-site-config-fichier ini

env = LANG=en_US.utf8
2
répondu luke_aus 2018-04-12 20:50:20

aucune des réponses n'a fonctionné pour moi (en utilisant Apache sur Ubuntu avec Django 1.10); j'ai choisi de supprimer les accents du nom du fichier (normaliser) comme ci-dessous:

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)
0
répondu SaeX 2017-03-15 19:41:34