一个奇怪的 Python/Django 中文文件编码问题

2014-03-14 17:00:25 +08:00
 guoqiao
我有一个Django站点 http://readfree.me ,托管了一些电子书.

当读取文件名含有中文的电子书的size时, 就会出现编码错误:
...
z = f(self.doc.size)
File "/root/.envs/readfree/local/lib/python2.7/site-packages/django/db/models/fields/files.py", line 71, in _get_size
return self.storage.size(self.name)
File "/root/.envs/readfree/local/lib/python2.7/site-packages/django/core/files/storage.py", line 250, in size
return os.path.getsize(self.path(name))
File "/root/.envs/readfree/lib/python2.7/genericpath.py", line 49, in getsize
return os.stat(filename).st_size
UnicodeEncodeError: 'ascii' codec can't encode characters in position 53-60: ordinal not in range(128)

(请忽略这里的f函数, 错误出在获取doc.size时)

补充说明:
1. 部署环境: Ubuntu Server + Nginx + uwsgi
2. 如果文件名不含中文,则没有问题
3. 使用uwsgi的emperor mode后台启动网站时才出现此问题
4. 如果ssh登陆到服务器,手工执行uwsgi --ini readfree.ini 来运行网站, 则没问题(目前就是这么做的,所以每个版本后面的size显示正常)
5. 在使用uwsgi之前, 用supervisor + gunicorn部署过, 出现同样的问题.
6. 直接在服务器上 ./manage.py runserver或者./manage.py run_gunicorn来运行网站, 也没问题.

从目前的情况看, 当使用后台运行的方式启动网站(uwsgi emperor mode, 或 supervisor), 中文文件就会出错. 而如果ssh登陆上去,手工运行网站, 则OK. 看起来最有可能是环境变量导致的.

尝试过在wsgi.py中增加LC_ALL设置:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
os.environ['LC_ALL']="en_US.UTF-8"
问题依旧.

阅读了各种关于编码的文章, 尝试了能想到的各种方法, 都没有解决.
可能是我对字符编码的理解还是太肤浅了, 有哪位同学可以指点一二?
5878 次点击
所在节点    Python
2 条回复
binux
2014-03-14 17:09:14 +08:00
self.name.encode("utf8")
或者
sys.setdefaultencoding("utf8") #强烈不建议
guoqiao
2014-03-15 05:46:05 +08:00
@binux 发现只要在v2ex提问就有好运;)
问题解决. 方法是在uwsgi的ini配置文件里加上编码设置:

[uwsgi]
.....
env=DJANGO_SETTINGS_MODULE=settings
env=LC_ALL=zh_CN.UTF-8

困扰我好久了, 如释重负

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/104321

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX