在Djangopipe理中上传文件时出现UnicodeEncodeError

注意 :我在StackOverflow上问了这个问题,但我意识到这可能是一个更合适的地方来问这样的问题。

我试图通过Djangopipe理应用上传一个名为“Testaråäö.txt”的文件。

我在Debian 6服务器上运行Django 1.3.1,使用Gunicorn 0.13.4和Nginx 0.7.6.7。 数据库是PostgreSQL 8.4.9。 其他的Unicode数据保存到数据库没有问题,所以我想这个问题必须以某种方式与文件系统。

我已经设定了

http { charset utf-8; } 

在我的nginx.conf。 LC_ALL和LANG被设置为'sv_SE.UTF-8'。 运行“语言环境”validation这一点。 我甚至尝试在我的nginx初始化脚本中设置LC_ALL和LANG,以确保locale设置正确。

这是追溯:

 Traceback (most recent call last): File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/handlers/base.py", line 111, in get_response response = callback(request, *callback_args, **callback_kwargs) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 307, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 93, in _wrapped_view response = view_func(request, *args, **kwargs) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/views/decorators/cache.py", line 79, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/sites.py", line 197, in inner return view(request, *args, **kwargs) File "/srv/django/letebo/app/cms/admin.py", line 81, in change_view return super(PageAdmin, self).change_view(request, obj_id) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 28, in _wrapper return bound_func(*args, **kwargs) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 93, in _wrapped_view response = view_func(request, *args, **kwargs) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 24, in bound_func return func(self, *args2, **kwargs2) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/transaction.py", line 217, in inner res = func(*args, **kwargs) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 985, in change_view self.save_formset(request, form, formset, change=True) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 677, in save_formset formset.save() File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 482, in save return self.save_existing_objects(commit) + self.save_new_objects(commit) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 613, in save_new_objects self.new_objects.append(self.save_new(form, commit=commit)) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 717, in save_new obj.save() File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 460, in save self.save_base(using=using, force_insert=force_insert, force_update=force_update) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 504, in save_base self.save_base(cls=parent, origin=org, using=using) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 543, in save_base for f in meta.local_fields if not isinstance(f, AutoField)] File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/fields/files.py", line 255, in pre_save file.save(file.name, file, save=False) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/fields/files.py", line 92, in save self.name = self.storage.save(name, content) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 48, in save name = self.get_available_name(name) File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 74, in get_available_name while self.exists(name): File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 218, in exists return os.path.exists(self.path(name)) File "/srv/.virtualenvs/letebo/lib/python2.6/genericpath.py", line 18, in exists st = os.stat(path) UnicodeEncodeError: 'ascii' codec can't encode characters in position 52-54: ordinal not in range(128) 

我试着打开debugging运行Gunicorn,file upload没有任何问题。 我想这意味着这个问题与Nginx有关。 尽pipe如此,仍然打败我在哪里看。 这里是来自Gunicorn和Nginx的原始响应头文件,如果它有任何意义:

Gunicorn:

 HTTP/1.1 302 FOUND Server: gunicorn/0.13.4 Date: Thu, 09 Feb 2012 14:50:27 GMT Connection: close Transfer-Encoding: chunked Expires: Thu, 09 Feb 2012 14:50:27 GMT Vary: Cookie Last-Modified: Thu, 09 Feb 2012 14:50:27 GMT Location: http://my-server.se:8000/admin/cms/page/15/ Cache-Control: max-age=0 Content-Type: text/html; charset=utf-8 Set-Cookie: messages="yada yada yada"; Path=/ 

Nginx的:

 HTTP/1.1 500 INTERNAL SERVER ERROR Server: nginx/0.7.67 Date: Thu, 09 Feb 2012 14:50:57 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: close Vary: Cookie 500 

更新locale.getpreferredencoding()sys.getfilesystemencoding()输出'UTF-8'locale.getdefaultlocale()输出('sv_SE', 'UTF8') 。 这对我来说似乎是正确的,所以我仍然不知道为什么我不断收到这些错误。

在尝试上传非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”

  1. 我遵循这里列出的“成功”标题下的说明https://code.djangoproject.com/wiki/ExpectedTestFailures (没有解决问题)

     aptitude install language-pack-en-base 
  2. 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)的修复程序。

我在这里find了一个很好的答案,在那里,Karen给出了一些有用的信息:

https://groups.google.com/forum/?fromgroups#!topic/django-users/hwNL7i6IeIY

这导致了我:

https://code.djangoproject.com/wiki/ExpectedTestFailures

我为Ubuntu安装了缺less的“语言包”。 我以root身份运行在shell中:

 locale-gen en_US.UTF-8 

现在正在工作。

看起来,在Python的低层次中,有一些调用Glibc需要一些由locale-gen生成的编译文件才能正常工作。

我查看了http://packages.debian.org ,在Debian中没有这样的软件包。

尝试运行以下命令并在重新尝试之前重新启动守护程序:

 locale-gen sv_SE.UTF-8 

或者可能安装任何Debian特定语言环境/语言包,如果有的话。