2017-10-16 4 views
1

Dans mon projet Django j'ai un formulaire avec un champ ("title"). Dans ce domaine, l'utilisateur doit écrire en russe mais l'utilisateur peut écrire des lettres latines par erreur. Je veux les changer. J'utilise PYTHON 2.7. Le code suivant déclenche une erreur. Comment réparer cette erreur?Comment changer les lettres du texte en d'autres lettres | Python 2.7?

from string import maketrans 

eng = 'ETOPAHKXCBMetopahkxcbm' # English letters 
rus = 'ЕТОРАНКХСВМеторанкхсвм' # Russian letters 

def form_valid(self, form): 
    form.cleaned_data['title'].translate(maketrans(dict(zip(eng, rus)))) 
    form.save() 

erreur:

Traceback (most recent call last): 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner 
    response = get_response(request) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch 
    return handler(request, *args, **kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/edit.py", line 217, in post 
    return super(BaseCreateView, self).post(request, *args, **kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/edit.py", line 183, in post 
    return self.form_valid(form) 
    File "/home/nurzhan/dashboard.kase.kz/static_pages/views.py", line 54, in form_valid 
    form.cleaned_data['title'].translate(maketrans(dict(zip(eng, rus)))) 
TypeError: maketrans() takes exactly 2 arguments (1 given) 

Quand je viens d'utiliser form.cleaned_data['title'].translate(maketrans(eng, rus)) il soulève erreur:

Internal Server Error: /static_page/create/ 
Traceback (most recent call last): 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner 
    response = get_response(request) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch 
    return handler(request, *args, **kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/edit.py", line 217, in post 
    return super(BaseCreateView, self).post(request, *args, **kwargs) 
    File "/srv/envs/py27/lib/python2.7/site-packages/django/views/generic/edit.py", line 183, in post 
    return self.form_valid(form) 
    File "/home/nurzhan/dashboard.kase.kz/static_pages/views.py", line 54, in form_valid 
    form.cleaned_data['title'].translate(maketrans(eng, rus)) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-21: ordinal not in range(128) 
+0

supprime self de votre définition de fonction. –

+0

L'indice est dans 'maketrans() prend exactement 2 arguments (1 donné)' - Voir [string.maketrans (from, to)] (https://docs.python.org/2/library/string.html#string .maketrans) –

+0

Quand j'utilise simplement 'form.cleaned_data ['title']. translate (maketrans (eng, rus))' il déclenche une erreur 'UnicodeEncodeError: 'codec' ascii 'ne peut pas encoder les caractères en position 0-21: ordinal pas dans la gamme (128) ». Avez-vous des idées à ce sujet? –

Répondre

1

Vous pouvez le faire manuellement comme ceci:

a_string = u"abcdeFghijklmn" # Let say it is cyrillic with one latin letter represented here by 'F' (uppercase) 
# To change it to cyrillic i.e. here to lower latin you would do: 
l2c = {u"F": u"f"} # Map all latin to cyrillic for real 
l2c_get = l2c.get # Faster access but not necessary 
a_string = u"".join(
    l2c_get(x, x) for x in a_string) 

Bien sûr, vous pouvez utiliser la méthode unicode.translate() qui devrait faire la même chose. Lorsque votre 'a_string' est traitée, il suffit de la repousser vers django. Tous les latins cartographiés en cyrillique seront substitués. Faites juste attention que tout est unicode dans la cartographie. Si mettre la chaîne traduite à django soulève la UnicodeDecode/erreur de Coder, cela signifie que vous devriez essayer avant:

a_string = a_string.encode("utf-8", "ignore") 

UTF-8 en binaire devrait être acceptée.

2

Ça va rendre les choses un peu plus facile si vous utilisez littéraux Unicode dans votre code ainsi, de cette façon, vous devez vous soucier moins de problèmes de type str vs unicode. C'est la même chose que d'écrire tous vos littéraux de chaîne comme u'stuff' au lieu de simplement 'stuff'.

suivant - la fonction translate de unicode et de prendre string différents arguments - vous avez besoin d'un dict pour la cartographie unicode Unicode ordinaux à ordinaux ou des chaînes Unicode, nemaketrans qui est seulement pour str traductions.

Vous pouvez utiliser le ord intégré pour obtenir les valeurs ordinales de vos caractères Unicode.

Essayez ceci:

from __future__ import unicode_literals # Put this at the top of your source 

eng = 'ETOPAHKXCBMetopahkxcbm' # English letters 
rus = 'ЕТОРАНКХСВМеторанкхсвм' # Russian letters 

table = dict(zip(map(ord, eng), map(ord, rus))) 
assert eng.translate(table) == rus # Verifying translation 
+0

Bonjour! J'ai essayé de tester votre code mais malheureusement ça ne marche pas pour moi. Votre code ne déclenche pas d'erreur mais il ne change pas les lettres latines en cyrillique. As-tu d'autres idées? –