我想利用 webapp2 的本地化新功能,该功能还具有特定于区域设置的时间和货币格式。
Django 有一个名为 get_language_from_request 的好函数,我在完全迁移到 webapp2 之前使用了它,现在我使用 webapp2 中的 i18n 代替,我可以在使用 gettext 编写的本地化之间切换并编译为我的应用程序可以使用的名为 messages.mo 的文件读取和显示。然后,我确定并优先考虑了以下获取用户语言的方法: 1. HTTP GET 例如。hl=pt-br 用于巴西葡萄牙语 2. HTTP SESSION 变量我称为 i18n_language 3. Cookie 我应该设置和获取,但我不知道具体如何获取 4. HTTP 标头我可以获取,在这里我也不确切知道,我我正在寻找 djnango 如何get_language_from_request
使用我曾经使用过的便捷方式来实现它,现在我已经停止导入 django,我仍然希望为我现在基于 webapp2 的代码提供此功能。
def get_language_from_request(self, request):
"""
Analyzes the request to find what language the user wants the system to
show. If the user requests a sublanguage where we have a main language, we send
out the main language.
"""
if self.request.get('hl'):
self.session['i18n_language'] = self.request.get('hl')
return self.request.get('hl')
if self.session:
lang_code = self.session.get('i18n_language', None)
if lang_code:
logging.info('language found in session')
return lang_code
lang_code = Cookies(self).get(LANGUAGE_COOKIE_NAME)
if lang_code:
logging.info('language found in cookies')
return lang_code
accept = os.environ.get('HTTP_ACCEPT_LANGUAGE', '')
for accept_lang, unused in self.parse_accept_lang_header(accept):
logging.info('accept_lang:'+accept_lang)
lang_code = accept_lang
return lang_code
我看到 django 代码可用,但我不知道 webapp2 中的 i18n 做了多少,例如,如果没有 .mo 本地化,我是否必须处理 pt-br 等语言的后备? pt-br 和其他方言类似。
实际设置我可以使用的语言
i18n.get_i18n().set_locale(language)
我请求您帮助优先考虑获取用户语言的不同方式,我也想知道您的想法如何继续实施。还是您认为我可以只使用会话变量而不是对“完整”解决方案如此彻底,因为无论如何我主要针对地理用途修复语言,我现在唯一实际使用的翻译是巴西葡萄牙语和英语,但我想要它也准备好切换到西班牙语和俄语以及其他语言,因此我希望能够切换到用户语言并至少将其保存到 webapp2 会话并知道您对使用 cookie 和标头获取用户的想法语言。
我曾经从 django 获得 si 的原始代码看起来像这样,我不能再使用它了,因为它被锁定到 django.mo 文件并且特定于 django
def get_language_from_request(request):
"""
Analyzes the request to find what language the user wants the system to
show. Only languages listed in settings.LANGUAGES are taken into account.
If the user requests a sublanguage where we have a main language, we send
out the main language.
"""
global _accepted
from django.conf import settings
globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
supported = dict(settings.LANGUAGES)
if hasattr(request, 'session'):
lang_code = request.session.get('django_language', None)
if lang_code in supported and lang_code is not None and check_for_language(lang_code):
return lang_code
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
if lang_code and lang_code not in supported:
lang_code = lang_code.split('-')[0] # e.g. if fr-ca is not supported fallback to fr
if lang_code and lang_code in supported and check_for_language(lang_code):
return lang_code
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
for accept_lang, unused in parse_accept_lang_header(accept):
if accept_lang == '*':
break
# We have a very restricted form for our language files (no encoding
# specifier, since they all must be UTF-8 and only one possible
# language each time. So we avoid the overhead of gettext.find() and
# work out the MO file manually.
# 'normalized' is the root name of the locale in POSIX format (which is
# the format used for the directories holding the MO files).
normalized = locale.locale_alias.get(to_locale(accept_lang, True))
if not normalized:
continue
# Remove the default encoding from locale_alias.
normalized = normalized.split('.')[0]
if normalized in _accepted:
# We've seen this locale before and have an MO file for it, so no
# need to check again.
return _accepted[normalized]
for lang, dirname in ((accept_lang, normalized),
(accept_lang.split('-')[0], normalized.split('_')[0])):
if lang.lower() not in supported:
continue
langfile = os.path.join(globalpath, dirname, 'LC_MESSAGES',
'django.mo')
if os.path.exists(langfile):
_accepted[normalized] = lang
return lang
return settings.LANGUAGE_CODE
可以为每个请求执行此操作吗?而且我认为我还应该将标题设置为语言self.response.headers['Content-Language'] = language
根据我的期望,如果我选择使用 http 标头,我可以直接从 django 获取一些功能,但我不明白它的作用,所以也许你可以从 django 为我解释这段代码:
def parse_accept_lang_header(lang_string):
"""
Parses the lang_string, which is the body of an HTTP Accept-Language
header, and returns a list of (lang, q-value), ordered by 'q' values.
Any format errors in lang_string results in an empty list being returned.
"""
result = []
pieces = accept_language_re.split(lang_string)
if pieces[-1]:
return []
for i in range(0, len(pieces) - 1, 3):
first, lang, priority = pieces[i : i + 3]
if first:
return []
priority = priority and float(priority) or 1.0
result.append((lang, priority))
result.sort(lambda x, y: -cmp(x[1], y[1]))
return result
谢谢
更新
我发现我无法在请求处理程序的初始化函数中使用会话,可能是因为尚未创建会话对象。因此,我将用于从会话中获取语言的代码放在 BaseHandler 渲染函数中,它似乎可以工作。考虑标头或 cookie 值也很好。