UnicodeEncodeError:'ascii'编解码器不能编码字符
当上传非ASCII字符的文件时,我得到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) 查看完整的堆栈跟踪 。
我用MySQL和nginx和FastCGI运行Django 1.2。
这是一个根据Django Trac数据库修复的问题,但是我仍然有问题。 任何build议如何解决是受欢迎的。
编辑:这是我的形象领域:
 image = models.ImageField(_('image'), upload_to='uploads/images', max_length=100) 
	
 对于在Supervisor中运行Django时遇到这个问题的人来说,解决办法是在Supervisorconfiguration的supervisord部分添加如下内容: 
 environment=LANG="en_US.utf8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8" 
这解决了在Debian Squeeze上运行的Supervisor 3.0a8中的问题。
在必须在只接受ascii(如控制台或path)的地方显示unicodestring的情况下,您必须告诉Python您希望它尽可能地replace非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' 
在Django模板的谨慎处理中,编码问题在pipe理中是被阻止的,但是如果你曾经添加过自定义列并且忘记将值转换为ascii,或者你重写模型的str方法而忘记这么做,你将会得到同样的错误,防止模板渲染。
如果这个string被保存到你的(希望是utf8)数据库中,那就没有问题了,看起来你正在尝试上传一个使用非ascii字符的实体标题的文件。
希望这会有所帮助。 就我而言,我通过daemontools运行django。
设置
 export LANG='en_US.UTF-8' export LC_ALL='en_US.UTF-8' 
在运行脚本之前执行manage.py解决了上传文件名的问题
在调查了一些后,我发现我没有在我的主要Nginxconfiguration文件中设置字符集:
 http { charset utf-8; } 
通过增加上述内容,问题就消失了,我认为这是处理这个问题的正确方法。
akaihola的答案是有帮助的。 对于那些通过upstart脚本来pipe理由uWSGIpipe理的django应用的人,只需将这些行添加到/etc/init/yourapp.conf
 env LANG="en_US.utf8" env LC_ALL="en_US.UTF-8" env LC_LANG="en_US.UTF-8" 
它解决了我的问题。
 如前所述,它与locale有关。 例如,如果你使用gunicorn来为你的django application提供服务,你可能会有一个init.d脚本(或者像我这样的runit脚本),你可以在其中设置语言环境。 
 要解决file upload中的UnicodeEncodeError问题,请在运行应用程序的脚本中inputexport LC_ALL=en_US.UTF8 。 
 例如,这是我的(使用gunicorn和runit ): 
 #!/bin/bash export LC_ALL=en_US.UTF8 cd /path/to/app/projectname exec gunicorn_django -b localhost:8000 --workers=2 
此外,您可以检查您的模板中的语言环境,在您的视图中使用它:
 import locale data_to_tpl = {'loc': locale.getlocale(), 'lod_def': locale.getdefaultlocale()} 
 在你的模板中显示{{loc}} - {{loc_def}} 。 
您将获得有关您的区域设置的更多信息! 这对我来说非常有用。
很难说没有看到更多的代码,但它看起来与这个问题有关: UnicodeDecodeError尝试通过django默认的基于文件的后端保存文件 。
 通过Django票据提到,看起来你应该遵循类似于“如果你得到一个UnicodeEncodeError”部署文档的东西: 
  https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror 
(我知道这是为Apache / mod_python,但我的猜测是这是相同的文件系统编码的根本问题不是UTF-8,使用nginx时也有类似的修复)
编辑:从我可以告诉这个nginx模块将是等效修复: http : //wiki.nginx.org/NginxHttpCharsetModule
避免重写代码的另一个有用的选项是更改python的默认编码。
 如果你使用的是virtualenv,你可以改变(或创build如果不存在) env/lib/python2.7/sitecustomize.py并添加: 
 import sys sys.setdefaultencoding('utf-8') 
 或者,如果您在生产系统中,则可以对/usr/lib/python2.7/sitecustomize.py执行相同的操作 
如果你使用Django和Python 2.7这个修复它为我:
 @python_2_unicode_compatible class Utente(models.Model): 
请参阅https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.encoding.python_2_unicode_compatible
使用Python 2.7.8和Django 1.7,我通过导入解决了我的问题:
 from __future__ import unicode_literals 
 和使用force_text() : 
 from django.utils.encoding import force_text 
只是build立在这个线程和其他人的答案…
在尝试上传非ASCII字符的文件名时,我遇到了与genericpath.py相同的问题,它提供了一个UnicodeEncodeError。
我用python 2.7使用nginx,uwsgi和django。
一切工作本地,但不在服务器上
这里是我采取的步骤1.添加到/etc/nginx/nginx.conf(没有解决问题)
 http { charset utf-8; } 
- 我把这行添加到etc / default / locale(没有解决问题)
LANGUAGE = “的en_US.UTF-8”
- 
我遵循这里列出的“成功”标题下的说明https://code.djangoproject.com/wiki/ExpectedTestFailures (没有解决问题) aptitude install language-pack-en-base
- 
在https://code.djangoproject.com/ticket/17816上find了这个问题,这个问题build议在服务器上testing一个视图,看看区域设置信息; 
在你看来
 import locale locales = "Current locale: %s %s -- Default locale: %s %s" % (locale.getlocale() + locale.getdefaultlocale()) 
在你的模板中
 {{ locales }} 
对我来说,问题是我的Ubuntu服务器上没有语言环境和默认语言环境(尽pipe我的本地OSX开发机器上有它们),那么带有非ASCII文件名/path的文件将无法正确上传,导致Python引发UnicodeEncodeError ,但只在生产服务器上。
解
我把这个添加到我的网站和我的网站pipe理员uwsgiconfiguration文件例如/ etc / uwsgi-emperor / vassals / my-site-config-ini文件
 env = LANG=en_US.utf8 
没有答案为我工作(在Ubuntu上与Django 1.10使用Apache); 我select从文件名(normalize)中删除重音符号如下:
 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)