Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

unicode et django

11 réponses
Avatar
hervest
Bonjour,
J'ai des problèmes avec les accents en django que je n'arrive pas à résoudre. j'ai cette erreur qui s'affiche lorsque j'essaye d'afficher mon prénom "hervé".

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 4: ordinal not in range(128)

qu'est ce que je dois configurer pour que ça marche?

Merci et bonne année

10 réponses

1 2
Avatar
Méta-MCI \(MVP\)
Bonjour !

Alors, pour bien démarrer l'année, il va falloir donner quelques
précisions supplémentaires :
- quel est l'encodage de ton source ? (tout au début l'en-tête)
- l'encodage du source correspond-il bien à l'encodage utilisé par
ton éditeur, pour enregistrer le fichier ?
- as-tu essayé de préfixer la chaîne avec u ? (e.g. ch =
u'Hervé' )
- utilises-tu du décodage/encodage dans tes fonctions ? Avec les
options 'ignore' ou 'replace' ?

@+
--
Michel Claveau
Avatar
Bruno Desthuilliers
hervest a écrit :
Méta-MCI (MVP) a écrit le 02/01/2009 à 10h32 :
Bonjour !

Alors, pour bien démarrer l'année, il va falloir donner quelques
précisions supplémentaires :
- quel est l'encodage de ton source ? (tout au début l'en-tête)
- l'encodage du source correspond-il bien à l'encodage utilisé
par
ton éditeur, pour enregistrer le fichier ?
- as-tu essayé de préfixer la chaîne avec u ? (e.g. ch
>> u'Hervé' )
- utilises-tu du décodage/encodage dans tes fonctions ? Avec les
options 'ignore' ou 'replace' ?

@+
--
Michel Claveau


je ne connais rien de tout ça, j'ai juste mis dans mon setting.py

LANGUAGE_CODE = 'fr-fr'



Aucun rapport. Ca c'est pour l'internationalisation.

et comme django est par défaut encoder en utf8



Non.

je me disais qu'il n'y avait
rien à faire. Je dois commencer par quoi?Est ce que vous pouvez m'expliquer en
profondeur le problème pour pouvoir mieux le comprendre




On va essayer... L'encodage, c'est le format utilisé pour représenter
les caractères - c'est à dire le mapping entre un code informatique (sur
un ou deux octets) et un caractère. La notion d'encodage apparait
partout où il y a du contenu texte.

En interne, il est utilisé par ta machine pour enregistrer et relire les
fichiers textes - donc tous tes fichiers sources (python, html,
whatever). A ce niveau, c'est à toi de préciser (dans ton éditeur de
code) quel encodage tu veux utiliser pour un fichier.

En ce qui concerne le code source Python, si un encodage autre que ascii
est utilisé, il faut également le préciser (pour le compilo et
l'interpréteur) au début du source avec la syntaxe suivante:

# -*- coding:utf-8 -*-

Dans ton SGBDR, l'encodage est utilisé pour le stockage *et* la
communication avec le client. La manière de régler ça dépend du SGBDR,
donc se reporter à la doc.

Dans le cadre d'une requête HTTP renvoyant un contenu de type text, il
convient de préciser _dans la réponse_ quel est l'encodage utilisé. Ceci
se fait soit directement dans les entêtes de la réponse (dans Django,
dans l'objet HttpResponse), soit si le contenu est de type text/html
dans la section <head /> du document, en utilisant une balise meta, ie:

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

Il faut *bien sûr* que l'encodage précisé corresponde à l'encodage
_effectif_ du contenu renvoyé !-)

Là où ça devient compliqué, c'est quand tu te retrouves avec du code
source Python + des templates HTML + une base de données + un serveur
web. Le meilleur moyen que je connaisse pour ne pas être emmerdé est de
prendre l'habitude de *toujours* utiliser le même encodage *partout* -
de préférence utf-8. Ca simplifie grandement la vie.
Avatar
Bruno Desthuilliers
hervest a écrit :
Bonjour,
J'ai des problèmes avec les accents en django que je n'arrive pas à résoudre.
j'ai cette erreur qui s'affiche lorsque j'essaye d'afficher mon prénom "hervé".

UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position 4:
ordinal not in range(128)

qu'est ce que je dois configurer pour que ça marche?



Aucune idée. Désolé, ma boule de cristal est en panne. Mais peut-être
que si tu nous montrait le code source, on aurait une chance d'y voire
plus clair ?-)
Avatar
hervest
Méta-MCI (MVP) a écrit le 02/01/2009 à 10h32 :
Bonjour !

Alors, pour bien démarrer l'année, il va falloir donner quelques
précisions supplémentaires :
- quel est l'encodage de ton source ? (tout au début l'en-tête)
- l'encodage du source correspond-il bien à l'encodage utilisé
par
ton éditeur, pour enregistrer le fichier ?
- as-tu essayé de préfixer la chaîne avec u ? (e.g. ch
=
u'Hervé' )
- utilises-tu du décodage/encodage dans tes fonctions ? Avec les
options 'ignore' ou 'replace' ?

@+
--
Michel Claveau


je ne connais rien de tout ça, j'ai juste mis dans mon setting.py

LANGUAGE_CODE = 'fr-fr'

et comme django est par défaut encoder en utf8 je me disais qu'il n'y avait rien à faire. Je dois commencer par quoi?Est ce que vous pouvez m'expliquer en profondeur le problème pour pouvoir mieux le comprendre

Merci
Avatar
Méta-MCI \(MVP\)
Re !

Il ya plusieurs notions à vérifier.

D'abord, l'en-tête du script indique quel sera l'encodage par défaut,
pour les chaînes littérales du script. Il faut, bien sûr, que l'éditeur
respecte les même encodage.

Pour être en UTF-8, l'en-tête doit être :
# -*- coding: utf-8 -*-

La notion suivante, c'est l'encodage utilisé par la cible. Pour django,
je ne sais pas (mais je suppose utf-8). Pour la console de Windows,
c'est CP850 (mais, la mienne utilise CP1252).

Donc, si, par exemple, tu pars d'une chaîne en cp1252, et tu cibles de
l'utf-8, il faudra faire un truc du genre :

chaine = "1 Aéèëê€"
inter = chaine.decode('cp1252','replace')
sortie = inter.encode('utf-8','replace')
ou, plus compact :
sortie = inter.decode('cp1252','replace').encode('utf-8','replace')


Le second paramètre pour decode / encode, indique ce que Python doit
faire, en cas d'erreur de caractère. Les valeurs les plus courantes
sont :
'strict' valeur par défaut ; provoquera une erreur
'ignore' ignore le caractère, et continue
'replace' remplace le caractère par un caractère de remplacement
(le ? ou un carré, ou autre, selon le système)


Si on préfixe la chaîne littérale avec u , elle sera enregistrée en
Unicode (en utilisant le type d'encodage de l'en-tête du script), et on
pourra économiser la phase de décodage. Exemple :
chaine = u"2 Aéèëê€"
sortie = chaine.encode('utf-8','replace')


Deux autres exemples, si on utilise l'en-tête de script utf-8, et on
cible CP850 :
chaine = "3 Aéèëê€"
sortie = chaine.decode('utf-8','replace').encode('cp850','replace')

chaine = u"4 Aéèëê€"
sortie = chaine.encode('cp850','replace')




Autre notion : la cible doit être capable de visualiser les caractères
utilisés. Et, notamment, les polices de caractères nécessaires doivent
être installées.
A noter que HTML utilise des encodages de caractères spécifiques. Mais,
je pense que c'est Django qui s'en occupera.



@-salutations
--
Michel Claveau
Avatar
Bruno Desthuilliers
Méta-MCI (MVP) a écrit :
(snip)

A noter que HTML utilise des encodages de caractères spécifiques.



Non, pas du tout.

Mais,
je pense que c'est Django qui s'en occupera.



Non plus !-)

Je suppose que tu penses au entités html (du genre "&eacute;" etc). Ces
entités ne relèvent pas de l'encodage à proprement parler, et (sauf bien
sûr pour les caractères '<' et '>'), sont inutiles si le charset déclaré
dans l'entête HTTP (ou via le <meta http-equiv> qui va bien) correspond
bien à l'encodage du contenu de la réponse.

Et non, django ne remplacera pas un "é" (quelque soit l'encodage) par
son entité équivalente "&eacute;".

HTH
Avatar
hervest
hervest a écrit le 02/01/2009 à 00h36 :
Bonjour,
J'ai des problèmes avec les accents en django que je n'arrive pas
à résoudre. j'ai cette erreur qui s'affiche lorsque j'essaye
d'afficher mon prénom "hervé".

UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position 4:
ordinal not in range(128)

qu'est ce que je dois configurer pour que ça marche?

Merci et bonne année


Merci a vous tous, j'ai remplacer les charset dans les pages html utf8, et dans les fichiers .py de django j'ai placé: # -*- coding: utf-8 -*- . j'ai ajouté dans setting.py

DEFAULT_CHARSET='utf-8'

mais rien n'a changé

Voici ce que j'ai fait
J'ai créé un utilisateur user avec l'adiministration de django et je lui ai donné comme username et last name hervé. j'ai voulu l'afficher avec ce code

python manage.py shell

from django.contrib.auth.models import User
use=User.objects.get(username='root')
print use.last_name





c'est là où j'ai eu cette erreur:

UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position
4: ordinal not in range(128)

aussi en définissant les models pour qu'ils me génèrent automatiquement des formulaires d'insertion (form for model)

class Employeur(models.Model):
nom_emp=models.CharField(max_lengthE, verbose_name="Libelle de la societe")
tel_emp=models.CharField(max_length, verbose_name="téléphone")

le 'é' de téléphone cause une erreur semblable à l'autre en lançant le serveur web

SyntaxError: Non-ASCII character 'xe9' in file /home/projet/airfast/../airfast/aerien/models.py on line 16, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

j'ai essayer ceci

class Employeur(models.Model):
tel="téléphone"
tel.encode('utf-8')
nom_emp=models.CharField(max_lengthE, verbose_name="Libelle de la societe")
tel_emp=models.CharField(max_length , verbose_name=tel)

mais dès qu'il voit le 'é' la console affiche des erreurs
Avatar
Bruno Desthuilliers
hervest a écrit :
hervest a écrit le 02/01/2009 à 00h36 :
Bonjour,
J'ai des problèmes avec les accents en django que je n'arrive pas
à résoudre. j'ai cette erreur qui s'affiche lorsque j'essaye
d'afficher mon prénom "hervé".

UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position


4:
ordinal not in range(128)

qu'est ce que je dois configurer pour que ça marche?

Merci et bonne année


Merci a vous tous, j'ai remplacer les charset dans les pages html utf8, et dans
les fichiers .py de django j'ai placé: # -*- coding: utf-8 -*- .



Je repète : il ne suffit pas de _déclarer_ que c'est de l'utf-8 pour que
ça en devienne. Pas plus que de renommer un fichier toto.doc en toto.jpg
n'en fait un fichier jpeg...

j'ai ajouté
dans setting.py

DEFAULT_CHARSET='utf-8'

mais rien n'a changé

Voici ce que j'ai fait
J'ai créé un utilisateur user avec l'adiministration de django et je lui ai
donné comme username et last name hervé. j'ai voulu l'afficher avec ce code

python manage.py shell

>from django.contrib.auth.models import User
use=User.objects.get(username='root')
print use.last_name





c'est là où j'ai eu cette erreur:



Ca ne concerne donc pas ton code source...

UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position
4: ordinal not in range(128)



Je viens de faire cette même manip (Django 1.0, Python 2.5.1, base
sqlite, le tout sous gentoo-linux), et je n'ai pas ce problème.

Que se passe-t'il si tu lance un shell Python (pas forcément via
"manage.py shell" ), et que tu tape le code suivant:

>>> s = "ééé"
>>> print s


aussi en définissant les models pour qu'ils me génèrent automatiquement des
formulaires d'insertion (form for model)

class Employeur(models.Model):
nom_emp=models.CharField(max_lengthE, verbose_name="Libelle de la
societe")
tel_emp=models.CharField(max_length, verbose_name="téléphone")



Utilise des chaines unicode ici:

nom_emp=models.CharField(
max_lengthE,
verbose_name=u"Libellé de la société" # XXX : fix copy/paste
)
tel_emp=models.CharField(
max_length,
verbose_name=u"téléphone"
)


<hs>
pourquoi le '_emp' ?
</hs>

le 'é' de téléphone cause une erreur semblable à l'autre en lançant le serveur
web



Au moment où le module est chargé, donc...

SyntaxError: Non-ASCII character 'xe9' in file
/home/projet/airfast/../airfast/aerien/models.py on line 16, but no encoding
declared; see http://www.python.org/peps/pep-0263.html for details



Parce que tu n'a pas de déclaration d'encodage en tête de ton .py (bis:
l'encodage déclaré doit être l'encodage effectif utilisé pour
sauvegarder le fichier). Et ça n'a rien de spécifique à Django, tu aura
le même résultat dans n'importe quel source Python.


j'ai essayer ceci

class Employeur(models.Model):
tel="téléphone"
tel.encode('utf-8')



str.encode ne modifie pas la chaine sur place (et pour cause), elle
retourne une nouvelle chaine. Donc cette opération ne sert à rien.
Accessoirement, les chaines Python sont des objets, tu peux donc
appeller directement une méthode sur un littéral, ie
"téléphone".encode(...). Mais ça ne résoudra toujours pas cette partie
de ton problème, qui est liée à l'absence de déclaration d'encodage en
tête du fichier.

nom_emp=models.CharField(max_lengthE, verbose_name="Libelle de la societe")
tel_emp=models.CharField(max_length , verbose_name=tel)

mais dès qu'il voit le 'é' la console affiche des erreurs



cf ci-dessus.
Avatar
hervest
Bruno Desthuilliers a écrit le 02/01/2009 à 17h04 :
hervest a écrit :
hervest a écrit le 02/01/2009 à 00h36 :
Bonjour,
J'ai des problèmes avec les accents en django que je n'arrive pas
à résoudre. j'ai cette erreur qui s'affiche lorsque j'essaye
d'afficher mon prénom "hervé".

UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position



4:
ordinal not in range(128)

qu'est ce que je dois configurer pour que ça marche?

Merci et bonne année



Merci a vous tous, j'ai remplacer les charset dans les pages html utf8, et
dans
les fichiers .py de django j'ai placé: # -*- coding: utf-8 -*- .




Je repète : il ne suffit pas de _déclarer_ que c'est de l'utf-8
pour que
ça en devienne. Pas plus que de renommer un fichier toto.doc en toto.jpg
n'en fait un fichier jpeg...

j'ai ajouté
dans setting.py

DEFAULT_CHARSET='utf-8'

mais rien n'a changé

Voici ce que j'ai fait
J'ai créé un utilisateur user avec l'adiministration de django
et je lui ai
donné comme username et last name hervé. j'ai voulu l'afficher
avec ce code

python manage.py shell

>from django.contrib.auth.models import User
use=User.objects.get(username='root')
print use.last_name







c'est là où j'ai eu cette erreur:




Ca ne concerne donc pas ton code source...

UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in position
4: ordinal not in range(128)




Je viens de faire cette même manip (Django 1.0, Python 2.5.1, base
sqlite, le tout sous gentoo-linux), et je n'ai pas ce problème.

Que se passe-t'il si tu lance un shell Python (pas forcément via
"manage.py shell" ), et que tu tape le code suivant:

>>> s = "ééé"
>>> print s


aussi en définissant les models pour qu'ils me génèrent
automatiquement des
formulaires d'insertion (form for model)

class Employeur(models.Model):
nom_emp=models.CharField(max_lengthE, verbose_name="Libelle de la
societe")
tel_emp=models.CharField(max_length,
verbose_name="téléphone")




Utilise des chaines unicode ici:

nom_emp=models.CharField(
max_lengthE,
verbose_name=u"Libellé de la société" # XXX :
fix copy/paste
)
tel_emp=models.CharField(
max_length,
verbose_name=u"téléphone"
)


<hs>
pourquoi le '_emp' ?
</hs>

le 'é' de téléphone cause une erreur semblable à
l'autre en lançant le serveur
web




Au moment où le module est chargé, donc...

SyntaxError: Non-ASCII character 'xe9' in file
/home/projet/airfast/../airfast/aerien/models.py on line 16, but no encoding
declared; see http://www.python.org/peps/pep-0263.html for details




Parce que tu n'a pas de déclaration d'encodage en tête de ton .py
(bis:
l'encodage déclaré doit être l'encodage effectif
utilisé pour
sauvegarder le fichier). Et ça n'a rien de spécifique à
Django, tu aura
le même résultat dans n'importe quel source Python.


j'ai essayer ceci

class Employeur(models.Model):
tel="téléphone"
tel.encode('utf-8')




str.encode ne modifie pas la chaine sur place (et pour cause), elle
retourne une nouvelle chaine. Donc cette opération ne sert à
rien.
Accessoirement, les chaines Python sont des objets, tu peux donc
appeller directement une méthode sur un littéral, ie
"téléphone".encode(...). Mais ça ne
résoudra toujours pas cette partie
de ton problème, qui est liée à l'absence de
déclaration d'encodage en
tête du fichier.

nom_emp=models.CharField(max_lengthE, verbose_name="Libelle de la
societe")
tel_emp=models.CharField(max_length , verbose_name=tel)

mais dès qu'il voit le 'é' la console affiche des erreurs




cf ci-dessus.


j'ai bien compri pour DEFAULT_CHARSET... on y vas donc pour le reste

environement de travail: django 1.0.2, python 2.5.1, sqlite3, freebsd-unix

1. Lorsque je rendre dans python (herve#python) à l'aide de mon shell je n'arrive pas à taper les accents il ya un bruit d'erreur

2. Lorsque je mets

verbose_name=u"Libellé de la société"

j'ai ceci:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 0: unexpected end of data

3. _emp devant les attributs des classes à cause de Employeur c'est juste pour dire "nom de l'employeur" (nom_emp)

4. est ce que ce n'est pas avec # -*- coding: utf-8 -*- que je dois faire la déclaration d'encodage de mes fichiers python? si oui je l'ais ai fait

au fait comment dois-je faire ici pour ne pas reprendre les questions que je reponds ou prendre des parties de la question que je veux repondre

Merci M.Bruno
Avatar
Bruno Desthuilliers
hervest a écrit :
(snip)

j'ai bien compri pour DEFAULT_CHARSET... on y vas donc pour le reste

environement de travail: django 1.0.2, python 2.5.1, sqlite3, freebsd-unix



Ok, jusque là c'est assez proche.

1. Lorsque je rendre dans python (herve#python) à l'aide de mon shell je
n'arrive pas à taper les accents il ya un bruit d'erreur



Ah. Donc un pb de config système quelque part (LANG, keyboard etc ?).

2. Lorsque je mets

verbose_name=u"Libellé de la société"

j'ai ceci:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 0:
unexpected end of data



"unexpected end of data" ??? Celui-là je ne l'ai jamais vu. Bon, je
pense vraiment que c'est un problème de config système avant tout.

3. _emp devant les attributs des classes à cause de Employeur c'est juste pour
dire "nom de l'employeur" (nom_emp)



Ah, Ok. Je pigeais pas trop.

<hs>
Je suis un brin puriste, j'aurais donc tendance à me demander si une
table "employeur" ne serait pas utile, mais bon, comme je ne sais rien
du domaine de l'application, c'est franchement prétentieux de ma part...
Bref, on va supposer que tu sais ce que tu fais et que je n'ai rien dit,
ça marche ?-)
</hs>

4. est ce que ce n'est pas avec # -*- coding: utf-8 -*- que je dois faire la
déclaration d'encodage de mes fichiers python?



Pour la _déclaration_ (attendue par l'interpréteur dès que tu des
caractères non-ascii dans ton source), oui. Mais c'est juste une
déclaration, ça ne change rien à l'encodage *effectif* du fichier. Si
ton fichier est encodé en latin1 et que le déclare en utf8, tu va avoir
au mieux des résultats bizarres (et possiblement des erreurs).

si oui je l'ais ai fait



C'est bien, mais seulement si ton fichier est effectivement encodé en
utf8. Je ne sais pas quel éditeur tu utilises, mais tout éditeur sérieux
te permet de spécifier l'encodage à utiliser pour ton fichier.

au fait comment dois-je faire ici pour ne pas reprendre les questions que je
reponds ou prendre des parties de la question que je veux repondre



Comme je viens de faire !-)

Merci M.Bruno



De rien M.Hervé, de rien. J'ai pas mal galéré avec ces c... d'encodage,
et je compatis pleinement.

Bon, AMHA, tu devrais avant tout t'assurer que ton système est bien
configuré pour utiliser de l'utf-8 (ou du latin1 ou autre, mais bon,
honnêtement, le meilleur moyen que j'ai trouvé pour ne plus être emmerdé
est de faire tout systématiquement en utf-8). Là dessus, je pense qu'il
y a des newsgroup plus adaptés que celui-ci. Une fois que tu pourra
taper des caractères accentués dans ton shell, ça ira mieux !-)

Ensuite, assure-toi que ton fichier est *effectivement* encodé en utf-8.
Idem, regarde dans la doc de ton éditeur, sur le newsgroup ou forum
approprié etc.

Je ne me souviens plus s'il y a quelque chose de particulier à faire
pour sqlite - flag à la compilation ou autre - mais là aussi, la réponse
est ailleurs.

Une fois que tu aura vu tous ces points, il y a des chances que ça aille
mieux. Sinon, bin je sais pas mais on verra à ce moment là :(
1 2