上传带有非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)
请参阅full stack trace。
我用MySQL和nginx以及FastCGI运行Django 1.2。
这是根据Django Trac database修复的问题,但我仍然遇到问题。欢迎任何有关如何解决的建议。
编辑:这是我的图片栏:
image = models.ImageField(_('image'), upload_to='uploads/images', max_length=100)
答案 0 :(得分:39)
对于使用Supervisor运行Django时遇到此问题的任何人,解决方案是添加例如以下是Supervisor配置的supervisord
部分:
environment=LANG="en_US.utf8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8"
这解决了在Debian Squeeze上运行Supervisor 3.0a8的问题。
答案 1 :(得分:24)
在必须在只接受ascii的地方(如控制台或路径)中显示unicode字符串的情况下,您必须告诉Python您希望它替换非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模板来防止编码问题,但是如果你曾经添加过自定义列而忘记将值转换为ascii,或者覆盖了 str 方法模型而忘记这样做,你会得到同样的错误,阻止模板渲染。
如果将此字符串保存到您的(希望是utf8)数据库中就没有问题,看起来您正在尝试上传使用具有非ascii字符的实体标题的文件。
答案 2 :(得分:12)
希望这会有所帮助。 就我而言,我正在通过daemontools运行django。
设置
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'
执行manage.py之前在运行脚本中的解决了uploads filename
的问题答案 3 :(得分:12)
在对此进行调查后,我发现我没有在主要的Nginx配置文件中设置charset:
http {
charset utf-8;
}
通过添加上述内容,问题就消失了,我认为这是处理此问题的正确方法。
答案 4 :(得分:10)
akaihola的回答很有帮助。对于那些通过upstart脚本管理uWSGI运行django app的人,只需将这些行添加到/etc/init/yourapp.conf
env LANG="en_US.utf8"
env LC_ALL="en_US.UTF-8"
env LC_LANG="en_US.UTF-8"
它解决了我的问题。
答案 5 :(得分:4)
很难说没有看到更多的代码,但它看起来与这个问题有关:UnicodeDecodeError on attempt to save file through django default filebased backend。
通过阅读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
答案 6 :(得分:4)
如前所述,它与语言环境有关。例如,如果您使用gunicorn
来为django application
提供服务,则可能会有一个init.d
脚本(或者像我一样的runit脚本),您可以在其中设置区域设置。
要解决带文件上传的UnicodeEncodeError,请在运行应用程序的脚本中添加export 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}}
。
您将获得有关区域设置的更多信息!这对我来说非常有用。
答案 7 :(得分:4)
避免重写代码的另一个有用选项是更改python的默认编码。
如果您正在使用virtualenv,则可以更改(或创建,如果不存在)env/lib/python2.7/sitecustomize.py
并添加:
import sys
sys.setdefaultencoding('utf-8')
或者,如果您在生产系统中,则可以对/usr/lib/python2.7/sitecustomize.py
答案 8 :(得分:3)
如果您正在使用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
答案 9 :(得分:3)
使用python 2.7.8和Django 1.7,我通过导入解决了我的问题:
from __future__ import unicode_literals
并使用force_text()
:
from django.utils.encoding import force_text
答案 10 :(得分:2)
只是建立在这个线程及其他人的答案上......
我在genericpath.py遇到同样的问题,在尝试上传带有非ASCII字符的文件名时会出现UnicodeEncodeError。
我正在使用nginx,uwsgi和django和python 2.7。
一切都在本地工作,但不在服务器上
以下是我采取的步骤 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 建议在服务器上测试视图信息
在你看来
import locale
locales = "Current locale: %s %s -- Default locale: %s %s" % (locale.getlocale() + locale.getdefaultlocale())
在您的模板中
{{ locales }}
对我来说,问题是我的Ubuntu服务器上没有语言环境和默认语言环境(虽然我确实在我的本地OSX开发机器上有它们)然后使用python无法正确上传非ASCII文件名/路径的文件提出UnicodeEncodeError,但仅在生产服务器上。
<强>解决方案强>
我将此添加到我的网站和我的网站管理员uwsgi配置文件中 例如/ etc / uwsgi-emperor / vassals / my-site-config-ini file
env = LANG=en_US.utf8
答案 11 :(得分:0)
没有一个答案对我有用(在Ubuntu上使用Apache和Django 1.10);我选择从文件名中删除重音(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)