Skip to main content
 首页 » 编程设计

python之翻译时停用语言回退(Python Django i18n)

2025年02月15日36yyy_WW

我有一个国际化的 Python Django 应用程序。它目前使用两种语言;德语 (DE) 和法语 (FR)。

我已将所有 key (.po-/.mo-文件)翻译成德语并准备就绪,但对于法语,有些丢失了。

在 Django 设置中,我将“de”指定为 LANGUAGE_CODE。

我可以毫无问题地从一种语言切换到另一种语言。路由工作正常,我需要的所有其他功能都由 Django 中间件处理。

但是,在当前情况下,当我从德语切换到法语时,法语中缺少的所有键都只能退回到德语值。但我希望他们只默认使用他们的 key 。

例如
当前情景
分类(法语可用)-> 分类
Gratis Lieferung(法语不可用)-> Gratis Lieferung

预期场景
分类(法语可用)-> 分类
Gratis Lieferung(法语不可用)-> free.shipping.info

解决这个问题的干净解决方案是什么?我在 Django 文档中找不到任何内容。我想在不使用额外插件的情况下解决这个问题。

我想出的一个解决方案是只添加法语翻译中所有缺失的键,并将它们的值也作为它们的键,但这感觉不对。

例如在 django.po

中
msgid "searchsuggest.placeholder" 
msgstr "searchsuggest.placeholder" 

另一种可能的解决方案是不在 settings.py 中设置 LANGUAGE_CODE,它的工作方式与我希望的法语一样,例如我转到 mypage.com/fr/,我所有已翻译的键都显示正确的对应值,而未翻译的键仅显示为键(请参阅“预期场景”)。但是当我这样做时,德语版本只显示键,没有值。例如。我转到 mypage.com/(德语应该是隐含的),这是我看到的:

分类.菜单.标题
free.shipping.info

更多信息

我的urls.py

urlpatterns = i18n_patterns( 
    # app endpoints 
    url(r'^$', home, name='home'), 
    url(r'^cart', include('app.cart.urls')), 
    url(r'^', include('app.infra.url.urls')), 
    prefix_default_language=False, 
) 

我的settings.py

TIME_ZONE = 'UTC' 
LANGUAGE_CODE = 'de' 
LANGUAGES = [ 
    ('de', _('German')), 
    ('fr', _('French')), 
] 
LOCALE_PATHS = [ 
    ../a/dir 
] 
USE_I18N = True 
USE_L10N = True 
USE_TZ = True 
 
# And somewhere I use this 
'django.middleware.locale.LocaleMiddleware', 

My jinja模板全局翻译功能:

from django.utils.translation import ugettext as _ 
from jinja2.ext import Extension 
 
class ViewExtension(Extension): 
    def __init__(self, environment): 
        super(ViewExtension, self).__init__(environment) 
        environment.globals['trans'] = trans 
 
# defaults back to german if not found 
def trans(translation_key, **kwargs): 
    translation = _(translation_key) % kwargs 
 
    if translation == translation_key: 
        # this only happens if my LANGUAGE_CODE is not set 
        translation_logger.warning(f'Missing translation key "{translation_key}".') 
 
    return translation 

请您参考如下方法:

如果有人对此有“适当”的解决方案,我仍然很高兴,但我最终用 shell 脚本解决了它:

#!/bin/bash 
 
# A simple script to make sure that all translation files contain all the msgids. 
# If a msgid previously didn't exist in a file, it will be created with the msgstr set to the same as the msgid. 
 
SCRIPTPATH=`dirname $0` 
MSGIDS=`find $SCRIPTPATH -name "*.po" -type f -print0 | xargs grep -h msgid | sort | uniq | awk '{print $2}'` 
 
find $SCRIPTPATH -name "*.po" -type f | while read FILE; do 
    current_msgids=`grep -h msgid $FILE | awk '{print $2}'` 
    for msg in $MSGIDS; do 
        [[ $current_msgids =~ (^|[[:space:]])"$msg"($|[[:space:]]) ]] || printf "\nmsgid $msg\nmsgstr $msg\n" >> $FILE 
    done 
done 

在我们的 Makefile 中运行 compilemessages 之前,我刚刚包含了这个脚本。