django 国际化详解与源码分析

2016/5/17 posted in  python

django 国际化

调试国际化环境

首次按照教程直接执行,在windows或者mac下面都会报相关的错误,需要我们安装gettext包。否则会报错

CommandError:Can't find msguniq. Make sure you have GNU gettext tools 0.15 or newer installed

此时表示gettext环境没有安装,在mac下需要安装brew之后安装gettext。

安装步骤如下:

  1. Install Homebrew : _usr_bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  2. Install GNU gettext : brew install gettext
  3. Create symlink : brew link gettext --force

安装完成后,gettext的默认是不会加到环境变量中的,需要我们手动添加到相关环境变量

export PATH=$PATH:/usr/local/Cellar/gettext/0.19.5.1/bin/

mac用户建议将这个加到开机的rc.local中去,否则每次都需要重新配置,比较麻烦

详情可以参考这个文档
http://stackoverflow.com/questions/23353113/django-admin-py-makemessages-not-working

这样安装完成后就可以在文档目录下面调用了,但是此时直接运行python django-admin.py makemessages ‐l zh_CN不会有任何反应。

解决makemessages运行问题

进到/Library/Python/2.7/site-packages/Django-1.9.6-py2.7.egg/django/core/management/commands里面可以查看到makemessages.py相应的源文件,仔细的读一下代码,发现其中的问题

可以看到最后的生成文件的方法是write_po_file(), 但是这个方法实际上是没有掉到的,往回跟可以发现问题出现在

def build_potfiles(self):
    """
    Build pot files and apply msguniq to them.
    """
    file_list = self.find_files(".")
    self.remove_potfiles()
    self.process_files(file_list)
    potfiles = []
    for path in self.locale_paths:
        potfile = os.path.join(path, '%s.pot' % str(self.domain))
        if not os.path.exists(potfile):
            continue
        args = ['msguniq'] + self.msguniq_options + [potfile]
        msgs, errors, status = gettext_popen_wrapper(args)
        if errors:
            if status != STATUS_OK:
                raise CommandError(
                    "errors happened while running msguniq\n%s" % errors)
            elif self.verbosity > 0:
                self.stdout.write(errors)
        with io.open(potfile, 'w', encoding='utf-8') as fp:
            fp.write(msgs)
        potfiles.append(potfile)
    return potfiles

这个方法里面,可以看到程序会去搜索一个pot之类的后缀的文件,如果locale下没有任何文件的话程序会直接continue到最后,既不能生成任何的文件。所以在locale下面需要放置一个文件,然后在执行python django-admin.py makemessages ‐l zh_CN就可以生成。

一些原理

问题解决的一些原理分享

  1. 默认使用第一次只会生成相应的po文件,po文件会去搜索当前目录下面的所有文件中的国际化字段,然后在该文件中自动添加,也会添加相关注释告知相应的国际化文件属于哪个文件,方便翻译。
  2. 需要在默认的middleware_classes配置文件下添加配置才可以生效。

生效代码:

MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
  1. 当修改完成配置之后可以再执行django-admin.py compilemessages , 将po文件编译成为mo文件。
  2. 测试方法,使用chrome,设置——高级设置——语言——语言和输入设置,将英文放到最上面去即可,参考

  3. 相关的配置可以参考几个网站

http://www.cnblogs.com/oubo/archive/2012/04/05/2433690.html
http://www.oschina.net/question/12_15775?fromerr=JlvW0sS9
官方文档

特别注意

django 1.9版本的中文国家化名称是 zh_Hans , 不在是以前的zh_cn
后面配置的时候需要注意。

locale目录需要配置在自己的当前目录下面,每个APP可以有自己的国际化目录。