Lors du téléchargement de fichiers contenant 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)
Voir trace de pile complète .
Je lance Django 1.2 avec MySQL et nginx et FastCGI.
C'est un problème qui est corrigé en fonction de la base de données Django Trac , mais j'ai toujours le problème Toutes les suggestions sur la façon de réparer sont les bienvenues.
EDIT: Ceci est mon champ d’image:
image = models.ImageField(_('image'), upload_to='uploads/images', max_length=100)
Après avoir enquêté davantage sur cette question, j'ai découvert que je n'avais pas défini le jeu de caractères dans mon fichier de configuration principal Nginx:
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 ce problème.
Pour toute personne rencontrant ce problème lors de l'exécution de Django avec Supervisor , la solution consiste à 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 Supervisor 3.0a8 sous Debian Squeeze.
Dans les cas où vous devez afficher une chaîne Unicode à un emplacement qui accepte uniquement les caractères ASCII (comme la console ou sous forme de chemin), vous devez indiquer à Python que vous souhaitez remplacer les caractères non ASCII au mieux.
>> 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 des modèles Django, mais si vous avez déjà ajouté des colonnes personnalisées et oublié de convertir les valeurs en ascii, ou si vous substituez la méthode str à un modèle et oubliez de le faire. , vous obtiendrez la même erreur, empêchant le rendu du modèle.
Si cette chaîne était sauvegardée dans votre base de données (espérons-le, utf8), il n'y aurait aucun problème, il semblerait que vous essayiez de télécharger un fichier utilisant le titre d'une entité comportant un caractère non ascii.
J'espère que cela vous aidera… .. Dans mon cas, je dirige Django dans daemontools.
Réglage
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'
dans le script d'exécution avant d'exécuter manage.py a résolu le problème de téléchargement du nom de fichier
la réponse d'Akaihola fut utile. Pour ceux qui exécutent l'application Django avec uWSGI géré via un script d'installation, ajoutez 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"
Cela a résolu le problème pour moi.
Comme dit précédemment, il est lié aux paramètres régionaux. Par exemple, si vous utilisez gunicorn
pour servir votre Django application
, vous pouvez avoir un script init.d
(ou, comme moi, un script runit) dans lequel vous pouvez définir les paramètres régionaux.
Pour résoudre UnicodeEncodeError avec le téléchargement de fichier, insérez quelque chose comme export LC_ALL=en_US.UTF8
dans votre script qui exécute 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
De plus, vous pouvez vérifier vos paramètres régionaux dans votre modèle, en utilisant ceci dans votre vue:
import locale
data_to_tpl = {'loc': locale.getlocale(), 'lod_def': locale.getdefaultlocale()}
Et indiquez simplement {{loc}} - {{loc_def}}
dans votre modèle.
Vous aurez plus d'informations sur vos paramètres régionaux! C'était très utile pour moi.
Une autre option utile qui évite la réécriture du code consiste à modifier le codage par défaut pour python.
Si vous utilisez virtualenv vous pouvez modifier (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 de même pour /usr/lib/python2.7/sitecustomize.py
Il est difficile de dire sans voir un peu plus de code, mais cela semble lié à cette question: UnicodeDecodeError lors de la tentative de sauvegarde de fichier via le backend basé sur un fichier par défaut de Django .
En regardant à travers le ticket Django mentionné, il semblerait que vous devriez suivre quelque chose de similaire aux documents de déploiement sur "Si vous obtenez un UnicodeEncodeError":
https://docs.djangoproject.com/fr/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror
(Je sais que cela concerne Apache/mod_python, mais j’imagine qu’il s’agit du même problème fondamental: le codage du système de fichiers n’est pas UTF-8 et il existe un correctif similaire lors de l’utilisation de nginx)
EDIT: D'après ce que je peux dire, ce module nginx serait le correctif équivalent: http://wiki.nginx.org/NginxHttpCharsetModule
Si vous utilisez Django et Python 2.7, cela résout le problème pour moi:
@python_2_unicode_compatible
class Utente(models.Model):
voir https://docs.djangoproject.com/en/dev/ref/utils/#Django.utils.encoding.python_2_unicode_compatible
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
En partant des réponses de ce fil et d’autres ...
J'ai eu le même problème avec genericpath.py en donnant un UnicodeEncodeError lorsque je tentais 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 étapes que j'ai suivies 1. ajouté à /etc/nginx/nginx.conf (n'a pas résolu le problème)
http {
charset utf-8;
}
J'ai ajouté cette ligne à etc/default/locale (n'a pas résolu le problème)
LANGUAGE="en_US.UTF-8"
J'ai suivi les instructions énumérées sous la rubrique "Succès" https://code.djangoproject.com/wiki/ExpectedTestFailures (n'a pas résolu le problème)
aptitude install language-pack-en-base
Trouvé sur ce ticket https://code.djangoproject.com/ticket/17816 Qui suggère de tester une vue sur le serveur de ce qui se passait avec les informations de paramètres régionaux
À votre avis
import locale
locales = "Current locale: %s %s -- Default locale: %s %s" % (locale.getlocale() + locale.getdefaultlocale())
Dans votre template
{{ locales }}
Pour moi, le problème était que je n’avais pas d’environnement local ni d’environnement local par défaut sur mon serveur Ubuntu (même si je les avais sur ma machine de développement OSX locale), puis les fichiers avec des noms de fichiers autres que ASCII python soulève une erreur UnicodeEncodeError, mais uniquement sur le serveur de production.
Solution
Je l'ai ajouté à la fois à mon site et à mes fichiers de configuration d'administrateur d'uwsgi d'administrateur de site /etc/uwsgi-emperor/vassals/fichier my-site-config-ini
env = LANG=en_US.utf8
Aucune des réponses n'a fonctionné pour moi (utiliser Apache sur Ubuntu avec Django 1.10); J'ai choisi de supprimer les accents du nom de 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)