37

上传带有非 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 数据库修复的问题,但我仍然有问题。欢迎任何有关如何修复的建议。

编辑:这是我的图像字段:

image = models.ImageField(_('image'), upload_to='uploads/images', max_length=100)
4

12 回答 12

41

对于在使用Supervisor运行 Django 时遇到此问题的任何人,解决方案是将例如以下内容添加到supervisordSupervisor 的配置部分:

environment=LANG="en_US.utf8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8"

这解决了我在 Debian Squeeze 上运行的 Supervisor 3.0a8 的问题。

还要确保 Supervisor 通过运行重新读取配置:

supervisorctl reread
supervisorctl restart myservice

(感谢@Udi)


对于新贵,添加您的/etc/init/myservice.conf

env LANG="en_US.utf8"
env LC_ALL="en_US.UTF-8"
env LC_LANG="en_US.UTF-8"`

(感谢@Andrii Zarubin;有关更多信息,请参阅 Upstart 文档中的环境变量)

于 2012-06-11T19:04:15.137 回答
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 字符的实体标题的文件。

于 2010-09-16T02:26:01.397 回答
14

希望这会有所帮助。就我而言,我正在通过 daemontools 运行 django。

环境

export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'

在执行 manage.py 之前的运行脚本中解决了上传文件名的问题

于 2011-07-04T14:59:59.997 回答
12

在对此进行了更多调查后,我发现我没有在我的主 Nginx 配置文件中设置字符集:

http {
  charset  utf-8;
}

通过添加上述内容,问题消失了,我认为这是处理此问题的正确方法。

于 2011-09-29T19:30:11.560 回答
11

akaihola 的回答很有帮助。对于那些使用通过 upstart 脚本管理的 uWSGI 运行 django 应用程序的人,只需将这些行添加到您的 /etc/init/yourapp.conf

env LANG="en_US.utf8"
env LC_ALL="en_US.UTF-8"
env LC_LANG="en_US.UTF-8"

它为我解决了这个问题。

于 2015-02-26T12:26:50.087 回答
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-你得到一个unicodeencodeerror

(我知道这是针对 Apache/mod_python 但我的猜测是文件系统编码不是 UTF-8 的相同根本问题,并且在使用 nginx 时有类似的修复)

编辑:据我所知,这个 nginx 模块将是等效的修复:http ://wiki.nginx.org/NginxHttpCharsetModule

于 2010-09-15T15:47:37.920 回答
4

如前所述,它与语言环境有关。例如,如果您使用gunicorn来服务您的django application,您可能有一个init.d脚本(或者,像我一样,一个 runit 脚本),您可以在其中设置语言环境。

要通过文件上传解决 UnicodeEncodeError,export LC_ALL=en_US.UTF8请在运行应用程序的脚本中添加类似内容。

例如,这是我的(使用gunicornand 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}}在您的模板中显示。

您将获得有关您的区域设置的更多信息!这对我非常有用。

于 2012-03-09T15:37:20.787 回答
4

另一个避免重写代码的有用选项是更改 python 的默认编码。

如果您使用的是virtualenv,您可以更改(如果不存在则创建)env/lib/python2.7/sitecustomize.py并添加:

import sys
sys.setdefaultencoding('utf-8')

或者,如果您在生产系统中,您可以这样做/usr/lib/python2.7/sitecustomize.py

于 2014-11-20T12:41:35.317 回答
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

于 2014-05-09T13:56:02.480 回答
3

使用 python 2.7.8 和 Django 1.7,我通过导入解决了我的问题:

from __future__ import unicode_literals

并使用force_text()

from django.utils.encoding import force_text
于 2014-10-04T08:30:16.037 回答
3

只是建立在这个线程和其他线程的答案之上......

尝试上传带有非 ASCII 字符的文件名时,我遇到了 genericpath.py 给出 UnicodeEncodeError 的相同问题。

我在 python 2.7 中使用了 nginx、uwsgi 和 django。

在本地一切正常,但在服务器上却不行

这是我采取的步骤 1. 添加到 /etc/nginx/nginx.conf (没有解决问题)

http {
    charset utf-8;
}
  1. 我将此行添加到 etc/default/locale (没有解决问题)

    LANGUAGE="en_US.UTF-8"

  2. 我按照标题“成功” https://code.djangoproject.com/wiki/ExpectedTestFailures下列出的说明进行操作 (没有解决问题)

    aptitude install language-pack-en-base
    
  3. 在这张票上找到 https://code.djangoproject.com/ticket/17816 建议测试服务器上的视图以了解区域设置信息发生的情况

在你看来

import locale
locales = "Current locale: %s %s -- Default locale: %s %s" % (locale.getlocale() + locale.getdefaultlocale())

在您的模板中

{{ locales }}

对我来说,问题是我的 Ubuntu 服务器上没有语言环境和默认语言环境(尽管我在本地 OSX 开发机器上确实有它们)然后具有非 ASCII 文件名/路径的文件将无法正确上传,python 引发 UnicodeEncodeError ,但仅在生产服务器上。

解决方案

我将此添加到我的站点和站点管理员 uwsgi 配置文件中,例如 /etc/uwsgi-emperor/vassals/my-site-config-ini 文件

env = LANG=en_US.utf8
于 2015-06-23T11:24:38.023 回答
0

没有一个答案对我有用(在 Ubuntu 上使用 Apache 和 Django 1.10);我选择从文件名中删除重音符号(规范化),如下所示:

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)
于 2017-03-15T19:41:34.853 回答