我在使用Django的表单上遇到Unicode输入问题:
UnicodeEncodeError at / 'ascii' codec can't encode character u'\xe4' in position 7: ordinal not in range(128)
这种情况发生在gunicorn上,以及在调试模式下运行Django.我的form.py启用了unicode:
#!/usr/bin/python # -*- coding: utf-8 -*- from django import forms from django.core.mail import send_mail from django.core.mail import EmailMessage import datetime class RTForm(forms.Form): # ... institution_station = forms.CharField(max_length=75, label=u"Institute/Station*") # ...
视图是基于此创建的,目的是从输入构建电子邮件:
class RTview(FormView): template_name = 'rt-form.html' form_class = RTForm success_url = '/thanks/' def form_valid(self, form): # This method is called when valid form data has been POSTed. # It should return an HttpResponse. form.send_email() return super(RTview, self).form_valid(form)
send_email函数看起来像这样:
def send_email(self): email = EmailMessage( subject='New item', #body='Here is the message.', from_email=self.cleaned_data['email'], to=['foo@example.com']) # The dict fields of the form contains all defined fields incl. # their labels etc. So taking this we can match and check for the # validated data to fullfill our task. values = [] for i in self.fields.iteritems(): values.append(u"%s: \t%s" % (self[i[0]].label, str(self.cleaned_data[i[0]]) ) ) email.body = "\n".join(values) email.send()
将unicode放入时institution_station
,应用程序会响应上述错误,但是无法values.append()
进入send_email
.
回溯看起来像:
Internal Server Error: / Traceback (most recent call last): File "/home/frlan/.virtualenvs/gascylinders/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/home/frlan/.virtualenvs/gascylinders/local/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view return self.dispatch(request, *args, **kwargs) File "/home/frlan/.virtualenvs/gascylinders/local/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch return handler(request, *args, **kwargs) File "/home/frlan/.virtualenvs/gascylinders/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 171, in post return self.form_valid(form) File "/home/frlan/quellen/git/gascylinders-rt-frontend/gascylinders/rtfrontend/views.py", line 12, in form_valid form.send_email() File "/home/frlan/quellen/git/gascylinders-rt-frontend/gascylinders/rtfrontend/forms.py", line 124, in send_email values.append(u"%s: \t%s" % (self[i[0]].label, str(self.cleaned_data[i[0]]) ) ) UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 7: ordinal not in range(128)
我可能错过了什么?
我认为这里的问题是调用str(self.cleaned_data[i[0]])
,它会从unicode值中创建一个字节串.例如u"%s" % str(u"überwach!")
会失败,哪里u"%s" % unicode(u"überwach!")
可以正常工作(即使unicode
在这种情况下调用是多余的......)
编辑:添加一些细节:str(u"überwach!")
失败UnicodeEncodeError
,因为,在引擎盖下,它调用u"überwach!".encode("ascii")
,但ASCII无法处理变音符号...
可悲的是,我无法找到的文档中描述这个beaviour(str()
调用__str__
一个上unicode
对象,但是这是如何__str__
实现的?),但更多的话题,看到了Python的Unicode指南.