深入学习Django源码基础8 - Django中系统级国际化本地化

来源:互联网 发布:淘宝优品乐购 编辑:程序博客网 时间:2024/05/16 09:52

具体使用步骤与分析http://www.ibm.com/developerworks/cn/web/1101_jinjh_djangoi18n/


本篇主要分析系统级的方法。不涉及自定义的

代码太多,采用逆向部分源码法来学习分析

main.py源码

import osfrom django.utils.formats import *os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.settings')print get_format('DATETIME_INPUT_FORMATS')


时间部分

ISO_INPUT_FORMATS = {    'DATE_INPUT_FORMATS': ('%Y-%m-%d',),    'TIME_INPUT_FORMATS': ('%H:%M:%S', '%H:%M'),    'DATETIME_INPUT_FORMATS': (        '%Y-%m-%d %H:%M:%S',        '%Y-%m-%d %H:%M:%S.%f',        '%Y-%m-%d %H:%M',        '%Y-%m-%d'    ),}


settings.py中

__author__ = 'watsy'TIME_ZONE = 'Asia/Shanghai'LANGUAGE_CODE = 'en-us'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = TrueLANGUAGE_CODE = 'zh-cn'SECRET_KEY = 'm&vr890n*%65ed4!alhj!-d=24cz+#)0%5@dq_8bgc&0p'

进入get_format中,查看文件提供方法

_format_cache_format_modules_cacheISO_INPUT_FORMATSreset_format_cache()iter_format_modules()iter_format_modules(lang)get_format_modules(lange=None,reverse=False)get_format(format_type,lang=None,use_l10n=None)get_format_lazydate_format(value,format=None,use_l10n=None)time_format(value,format=None,use_l10n=None)....localize(value,use_l10n=None)...

下面的全部调用到get_format获取。因此进入get_format函数

def get_format(format_type, lang=None, use_l10n=None):    format_type = force_str(format_type)    if use_l10n or (use_l10n is None and settings.USE_L10N):        if lang is None:            lang = get_language()        cache_key = (format_type, lang)        try:            cached = _format_cache[cache_key]            if cached is not None:                return cached            else:                # Return the general setting by default                return getattr(settings, format_type)        except KeyError:            for module in get_format_modules(lang):                try:                    val = getattr(module, format_type)                    for iso_input in ISO_INPUT_FORMATS.get(format_type, ()):                        if iso_input not in val:                            if isinstance(val, tuple):                                val = list(val)                            val.append(iso_input)                    _format_cache[cache_key] = val                    return val                except AttributeError:                    pass            _format_cache[cache_key] = None    return getattr(settings, format_type)
首先判断是否支持国际化

  如果支持,并且提供语言

     获取语言
  生存缓存关键字

       获取缓存并返回

       异常以后加载国际化语言模块从新获取,并记录到缓存


因此重点分析获取语言模块提取部分

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

def get_format_modules(lang=None, reverse=False):    """    Returns a list of the format modules found    """    if lang is None:        lang = get_language()    modules = _format_modules_cache.setdefault(lang, list(iter_format_modules(lang)))    if reverse:        return list(reversed(modules))    return modules

获取格式化模块部分重点在list遍历生成部分

def iter_format_modules(lang):    """    Does the heavy lifting of finding format modules.    """    if check_for_language(lang):        format_locations = ['django.conf.locale.%s']        if settings.FORMAT_MODULE_PATH:            format_locations.append(settings.FORMAT_MODULE_PATH + '.%s')            format_locations.reverse()        locale = to_locale(lang)        locales = [locale]        if '_' in locale:            locales.append(locale.split('_')[0])        for location in format_locations:            for loc in locales:                try:                    yield import_module('.formats', location % loc)                except ImportError:                    pass

检查语言是否支持

   格式化语言模块

   加载

def import_module(name, package=None):    if name.startswith('.'):        if not package:            raise TypeError("relative imports require the 'package' argument")        level = 0        for character in name:            if character != '.':                break            level += 1        name = _resolve_name(name[level:], package, level)    __import__(name)    return sys.modules[name]

分析检查是否支持语言模块,最终定位到utils中translation下trans_real.py文件中

def check_for_language(lang_code):    for path in all_locale_paths():        if gettext_module.find('django', path, [to_locale(lang_code)]) is not None:            return True    return False

遍历本地化路径,判断多国语言的编码模块是否支持

进入本地化路径部分

def all_locale_paths():    from django.conf import settings    globalpath = os.path.join(        os.path.dirname(upath(sys.modules[settings.__module__].__file__)), 'locale')    return [globalpath] + list(settings.LOCALE_PATHS)

这段代码比较有意思,文件加载部分。

全局的代码会得到django.core.locale路径

本地化路径需要在settings.LOCALE_PATHS变量中设置。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------


获取语言部分

def get_language():    t = getattr(_active, "value", None)    if t is not None:        try:            return t.to_language()        except AttributeError:            pass    from django.conf import settings    return settings.LANGUAGE_CODE

得到当前激活的语言,否则返回settings.LANGUAGE_CODE语言


在来看本地化语言的路径。


这里与上一片本地化内容一样了。


其他函数经过分析可以看出来

trans_real.py 包装了python的本地化方法。针对http部分进行了增强

format.py文件提供格式化系统级别的一些多国语言函数


以后有时间在分析app内使用的原理~

原创粉丝点击