UnicodeEncodeError:“ascii”编码解码器无法编码字符。

时间:2023-01-06 13:20:56

When uploading files with non-ASCII characters I get UnicodeEncodeError:

当使用非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)

See full stack trace.

看到完整的堆栈跟踪。

I run Django 1.2 with MySQL and nginx and FastCGI.

我用MySQL和nginx和FastCGI运行Django 1.2。

This is a problem that is fixed according to the Django Trac database, but I still have the problem. Any suggestions on how to fix are welcome.

这是一个根据Django Trac数据库修复的问题,但我仍然有问题。任何关于如何修复的建议都是受欢迎的。

EDIT: This is my image field:

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

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

12 个解决方案

#1


37  

For anyone encountering this problem when running Django with Supervisor, the solution is to add e.g. the following to the supervisord section of Supervisor's configuration:

对于任何遇到这个问题的人,当与主管一起运行Django时,解决方案是添加如下:以下是主管配置的监督部分:

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

This solved the problem for me in Supervisor 3.0a8 running on Debian Squeeze.

这帮我解决了在Debian上运行的3.0a8管理员的问题。

#2


24  

In situations where you must display a unicode string in a place that only accepts ascii (like the console or as a path) you must tell Python that you want it to replace the non ascii characters best effort.

在某些情况下,必须在只接受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'

Encoding issues are prevented in the admin by the cautious handing of Django templating, but if you have ever added custom columns and forgotten to convert the values to ascii, or you override the str method for a model and forget to do this, you will get the same error, preventing template rendering.

编码问题是避免在管理谨慎处理的Django模板,但是如果你曾经添加自定义列和忘记将值转换为ascii,或者你覆盖模型和忘记的str方法做到这一点,你会得到同样的错误,防止模板渲染。

If this string were saved into your (hopefully utf8) database there would be no problem, it looks like you are trying to upload a file that uses the title of an entity that has a non ascii character.

如果将此字符串保存到您的(希望utf8)数据库中,那么就没有问题了,看起来您正在尝试上传一个文件,该文件使用具有非ascii字符的实体的标题。

#3


12  

Hope this would help. In my case, I'm running django through daemontools.

希望这将有助于。在我的例子中,我通过daemontools运行django。

Setting

设置

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

in run script before executing manage.py resolved the issue with uploads filename

在执行管理之前运行脚本。py解决了上传文件名的问题。

#4


12  

After investigating this some more I found out that I hadn't set the charset in my main Nginx config file:

在进一步调查之后,我发现我并没有在Nginx配置文件中设置charset:

http {
  charset  utf-8;
}

By adding the above, the problem disappeared and I think that this is the correct way of handling this issue.

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

#5


10  

akaihola's answer was helpful. For those who run django app with uWSGI managed via upstart script, just add these lines to your /etc/init/yourapp.conf

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"

It solved the problem for me.

它帮我解决了这个问题。

#6


4  

As said before, it is related to locale. For exemple, if you use gunicorn to serve your django application, you may have an init.d script (or, as me, a runit script), where you can set the locale.

如前所述,它与地区有关。例如,如果您使用gunicorn服务django应用程序,您可能会有一个init。d脚本(或者,如我,一个runit脚本),在那里您可以设置区域设置。

To solve UnicodeEncodeError with file upload, put something like export LC_ALL=en_US.UTF8 in your script that run your app.

为了解决文件上传的UnicodeEncodeError,可以输入export LC_ALL=en_US。运行应用程序的脚本中的UTF8。

For example, this is mine (using gunicorn and runit):

例如,这是我的(使用gunicorn和runit):

#!/bin/bash
export LC_ALL=en_US.UTF8
cd /path/to/app/projectname
exec gunicorn_django -b localhost:8000 --workers=2

Also, you can check your locale in your template, using this in your view:

此外,您还可以在模板中检查您的区域设置,在您的视图中使用它:

import locale
data_to_tpl = {'loc': locale.getlocale(), 'lod_def': locale.getdefaultlocale()}

And just disply {{loc}} - {{loc_def}} in your template.

并且在模板中只使用{{{}{{loc_def}}。

You will have more information about your locale settings! That was very usefull for me.

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

#7


4  

It's hard to say without seeing a little more code but it looks to be related to this question: UnicodeDecodeError on attempt to save file through django default filebased backend.

很难说没有看到更多的代码,但是它看起来与这个问题有关:UnicodeDecodeError试图通过django默认文件后端来保存文件。

Looking through the Django ticket mentioned it would seem you should follow something similar to the deployment docs on "If you get a UnicodeEncodeError":
https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror

查看Django罚单时,您可能会看到类似于“如果您得到了一个UnicodeEncodeError”的部署文档:https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/# If - youget - UnicodeEncodeError。

(I know this is for Apache/mod_python but my guess would be it's the same root issue of file system encoding not being UTF-8 and there is a similar fix when using nginx)

(我知道这是Apache/mod_python的,但我的猜测是,文件系统编码的根本问题不是UTF-8,在使用nginx时也有类似的解决方案)

EDIT: From what I can tell this nginx module would be the equivalent fix: http://wiki.nginx.org/NginxHttpCharsetModule

编辑:从我可以看出这个nginx模块将是等价的修复:http://wiki.nginx.org/NginxHttpCharsetModule。

#8


4  

Another useful option that avoids rewriting code is to change the default encoding for python.

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

If you're using virtualenv you can change (or create if doesn't exist) env/lib/python2.7/sitecustomize.py and add:

如果您正在使用virtualenv,您可以更改(或创建如果不存在)env/lib/python2.7/sitecustomize。py和添加:

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

or, if you are in a production system, you can do the same to /usr/lib/python2.7/sitecustomize.py

或者,如果您在一个生产系统中,您可以对/usr/lib/python2.7/sitecustomize.py进行同样的操作。

#9


3  

If you're using django and python 2.7 this fixes it for me:

如果你正在使用django和python 2.7,这将为我修复它:

@python_2_unicode_compatible
class Utente(models.Model):

see https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.encoding.python_2_unicode_compatible

看到https://docs.djangoproject.com/en/dev/ref/utils/ django.utils.encoding.python_2_unicode_compatible

#10


3  

Using python 2.7.8 and Django 1.7, I solved my problem by importing:

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

from __future__ import unicode_literals

and using force_text():

和使用force_text():

from django.utils.encoding import force_text

#11


1  

Just building on answers from this thread and others...

从这个线程和其他人的答案中构建…

I had the same issue with genericpath.py giving a UnicodeEncodeError when attempting to upload a file name with non ASCII characters.

我对genericpath也有同样的问题。在尝试使用非ASCII字符上传文件名称时,py提供了一个UnicodeEncodeError。

I was using nginx, uwsgi and django with python 2.7.

我使用的是nginx, uwsgi, django和python 2.7。

Everything was working OK locally but not on the server

一切都在本地运行,但服务器上没有。

Here are the steps I took 1. added to /etc/nginx/nginx.conf (did not fix the problem)

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

http {
    charset utf-8;
}
  1. I added this line to etc/default/locale (did not fix the problem)
  2. 我将这一行添加到etc/default/locale(没有解决问题)

LANGUAGE="en_US.UTF-8"

语言= " en_US.UTF-8 "

  1. I followed the instructions here listed under the heading 'Success' https://code.djangoproject.com/wiki/ExpectedTestFailures (did not fix the problem)

    我遵循了标题“Success”https://code.djangoproject.com/wiki/expectedtestfailure(没有解决问题)的指示。

    aptitude install language-pack-en-base
    
  2. Found across this ticket https://code.djangoproject.com/ticket/17816 which suggested testing a view on the server to what was happening with locale information

    在这张票上找到了https://code.djangoproject.com/ticket/17816,它建议在服务器上测试本地信息。

In your view

在你的观点

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

In your template

在你的模板

{{ locales }}

For me, the issue was that I had no locale and no default locale on my Ubuntu server (though I did have them on my local OSX dev machine) then files with non ASCII file names/paths will not upload correctly with python raising a UnicodeEncodeError, but only on the production server.

对我来说,问题是,我没有语言环境,我的Ubuntu服务器上没有缺省语言环境(尽管我确实有他们在我当地的OSX dev机)然后用非ASCII文件/路径不会上传正确的文件的名称与python抚养UnicodeEncodeError,但只有在生产服务器上。

Solution

解决方案

I added this to both my site and my site admin uwsgi config files e.g. /etc/uwsgi-emperor/vassals/my-site-config-ini file

我把这个添加到我的网站和我的网站管理员uwsgi配置文件中,例如:/etc/uwsgi-emperor/vassals/my-site-config-ini文件。

env = LANG=en_US.utf8

#12


0  

None of the answers worked for me (using Apache on Ubuntu with Django 1.10); I chose to remove accents from the file name (normalize) as below:

没有一个答案对我起作用(使用Django 1.10在Ubuntu上使用Apache);我选择从文件名(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)

#1


37  

For anyone encountering this problem when running Django with Supervisor, the solution is to add e.g. the following to the supervisord section of Supervisor's configuration:

对于任何遇到这个问题的人,当与主管一起运行Django时,解决方案是添加如下:以下是主管配置的监督部分:

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

This solved the problem for me in Supervisor 3.0a8 running on Debian Squeeze.

这帮我解决了在Debian上运行的3.0a8管理员的问题。

#2


24  

In situations where you must display a unicode string in a place that only accepts ascii (like the console or as a path) you must tell Python that you want it to replace the non ascii characters best effort.

在某些情况下,必须在只接受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'

Encoding issues are prevented in the admin by the cautious handing of Django templating, but if you have ever added custom columns and forgotten to convert the values to ascii, or you override the str method for a model and forget to do this, you will get the same error, preventing template rendering.

编码问题是避免在管理谨慎处理的Django模板,但是如果你曾经添加自定义列和忘记将值转换为ascii,或者你覆盖模型和忘记的str方法做到这一点,你会得到同样的错误,防止模板渲染。

If this string were saved into your (hopefully utf8) database there would be no problem, it looks like you are trying to upload a file that uses the title of an entity that has a non ascii character.

如果将此字符串保存到您的(希望utf8)数据库中,那么就没有问题了,看起来您正在尝试上传一个文件,该文件使用具有非ascii字符的实体的标题。

#3


12  

Hope this would help. In my case, I'm running django through daemontools.

希望这将有助于。在我的例子中,我通过daemontools运行django。

Setting

设置

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

in run script before executing manage.py resolved the issue with uploads filename

在执行管理之前运行脚本。py解决了上传文件名的问题。

#4


12  

After investigating this some more I found out that I hadn't set the charset in my main Nginx config file:

在进一步调查之后,我发现我并没有在Nginx配置文件中设置charset:

http {
  charset  utf-8;
}

By adding the above, the problem disappeared and I think that this is the correct way of handling this issue.

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

#5


10  

akaihola's answer was helpful. For those who run django app with uWSGI managed via upstart script, just add these lines to your /etc/init/yourapp.conf

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"

It solved the problem for me.

它帮我解决了这个问题。

#6


4  

As said before, it is related to locale. For exemple, if you use gunicorn to serve your django application, you may have an init.d script (or, as me, a runit script), where you can set the locale.

如前所述,它与地区有关。例如,如果您使用gunicorn服务django应用程序,您可能会有一个init。d脚本(或者,如我,一个runit脚本),在那里您可以设置区域设置。

To solve UnicodeEncodeError with file upload, put something like export LC_ALL=en_US.UTF8 in your script that run your app.

为了解决文件上传的UnicodeEncodeError,可以输入export LC_ALL=en_US。运行应用程序的脚本中的UTF8。

For example, this is mine (using gunicorn and runit):

例如,这是我的(使用gunicorn和runit):

#!/bin/bash
export LC_ALL=en_US.UTF8
cd /path/to/app/projectname
exec gunicorn_django -b localhost:8000 --workers=2

Also, you can check your locale in your template, using this in your view:

此外,您还可以在模板中检查您的区域设置,在您的视图中使用它:

import locale
data_to_tpl = {'loc': locale.getlocale(), 'lod_def': locale.getdefaultlocale()}

And just disply {{loc}} - {{loc_def}} in your template.

并且在模板中只使用{{{}{{loc_def}}。

You will have more information about your locale settings! That was very usefull for me.

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

#7


4  

It's hard to say without seeing a little more code but it looks to be related to this question: UnicodeDecodeError on attempt to save file through django default filebased backend.

很难说没有看到更多的代码,但是它看起来与这个问题有关:UnicodeDecodeError试图通过django默认文件后端来保存文件。

Looking through the Django ticket mentioned it would seem you should follow something similar to the deployment docs on "If you get a UnicodeEncodeError":
https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror

查看Django罚单时,您可能会看到类似于“如果您得到了一个UnicodeEncodeError”的部署文档:https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/# If - youget - UnicodeEncodeError。

(I know this is for Apache/mod_python but my guess would be it's the same root issue of file system encoding not being UTF-8 and there is a similar fix when using nginx)

(我知道这是Apache/mod_python的,但我的猜测是,文件系统编码的根本问题不是UTF-8,在使用nginx时也有类似的解决方案)

EDIT: From what I can tell this nginx module would be the equivalent fix: http://wiki.nginx.org/NginxHttpCharsetModule

编辑:从我可以看出这个nginx模块将是等价的修复:http://wiki.nginx.org/NginxHttpCharsetModule。

#8


4  

Another useful option that avoids rewriting code is to change the default encoding for python.

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

If you're using virtualenv you can change (or create if doesn't exist) env/lib/python2.7/sitecustomize.py and add:

如果您正在使用virtualenv,您可以更改(或创建如果不存在)env/lib/python2.7/sitecustomize。py和添加:

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

or, if you are in a production system, you can do the same to /usr/lib/python2.7/sitecustomize.py

或者,如果您在一个生产系统中,您可以对/usr/lib/python2.7/sitecustomize.py进行同样的操作。

#9


3  

If you're using django and python 2.7 this fixes it for me:

如果你正在使用django和python 2.7,这将为我修复它:

@python_2_unicode_compatible
class Utente(models.Model):

see https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.encoding.python_2_unicode_compatible

看到https://docs.djangoproject.com/en/dev/ref/utils/ django.utils.encoding.python_2_unicode_compatible

#10


3  

Using python 2.7.8 and Django 1.7, I solved my problem by importing:

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

from __future__ import unicode_literals

and using force_text():

和使用force_text():

from django.utils.encoding import force_text

#11


1  

Just building on answers from this thread and others...

从这个线程和其他人的答案中构建…

I had the same issue with genericpath.py giving a UnicodeEncodeError when attempting to upload a file name with non ASCII characters.

我对genericpath也有同样的问题。在尝试使用非ASCII字符上传文件名称时,py提供了一个UnicodeEncodeError。

I was using nginx, uwsgi and django with python 2.7.

我使用的是nginx, uwsgi, django和python 2.7。

Everything was working OK locally but not on the server

一切都在本地运行,但服务器上没有。

Here are the steps I took 1. added to /etc/nginx/nginx.conf (did not fix the problem)

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

http {
    charset utf-8;
}
  1. I added this line to etc/default/locale (did not fix the problem)
  2. 我将这一行添加到etc/default/locale(没有解决问题)

LANGUAGE="en_US.UTF-8"

语言= " en_US.UTF-8 "

  1. I followed the instructions here listed under the heading 'Success' https://code.djangoproject.com/wiki/ExpectedTestFailures (did not fix the problem)

    我遵循了标题“Success”https://code.djangoproject.com/wiki/expectedtestfailure(没有解决问题)的指示。

    aptitude install language-pack-en-base
    
  2. Found across this ticket https://code.djangoproject.com/ticket/17816 which suggested testing a view on the server to what was happening with locale information

    在这张票上找到了https://code.djangoproject.com/ticket/17816,它建议在服务器上测试本地信息。

In your view

在你的观点

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

In your template

在你的模板

{{ locales }}

For me, the issue was that I had no locale and no default locale on my Ubuntu server (though I did have them on my local OSX dev machine) then files with non ASCII file names/paths will not upload correctly with python raising a UnicodeEncodeError, but only on the production server.

对我来说,问题是,我没有语言环境,我的Ubuntu服务器上没有缺省语言环境(尽管我确实有他们在我当地的OSX dev机)然后用非ASCII文件/路径不会上传正确的文件的名称与python抚养UnicodeEncodeError,但只有在生产服务器上。

Solution

解决方案

I added this to both my site and my site admin uwsgi config files e.g. /etc/uwsgi-emperor/vassals/my-site-config-ini file

我把这个添加到我的网站和我的网站管理员uwsgi配置文件中,例如:/etc/uwsgi-emperor/vassals/my-site-config-ini文件。

env = LANG=en_US.utf8

#12


0  

None of the answers worked for me (using Apache on Ubuntu with Django 1.10); I chose to remove accents from the file name (normalize) as below:

没有一个答案对我起作用(使用Django 1.10在Ubuntu上使用Apache);我选择从文件名(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)