V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
guoqiao
V2EX  ›  Python

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

  •  1
     
  •   guoqiao · 2014-03-14 17:00:25 +08:00 · 5877 次点击
    这是一个创建于 3941 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我有一个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"
    问题依旧.

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

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

    困扰我好久了, 如释重负
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2804 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 03:17 · PVG 11:17 · LAX 19:17 · JFK 22:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.