Xun*_*ang 2 python django localization internationalization
我在Django中创建了一些Badge类,每个类都包含一些字符串变量中的描述:
"You get this badge because you've runned %d meters in %d minutes"
"You get this badge because you've killed %d monsters of the type %s"
Run Code Online (Sandbox Code Playgroud)
这些类也有一个函数get_description(badge_level_requirements)
,因此在模板中它将与列表一起调用以组合特定用户的字符串:
class RunnerBadge(Badge):
des=ugettext_lazy("You get this badge because you've runned %d meters in %d minutes")
def get_description(cls,badge_level_requirements):
return cls.des%badge_level_requirements
Run Code Online (Sandbox Code Playgroud)
并且我已经将需求列表存储在数据库中而没有任何参数名称:(如示例所示,不同的类具有不同数量的值来填充字符串,值也意味着不同的东西.所以我不能真的命名参数.
但是,如果我想将这些字符串国际化,那么就会出现错误:'msgid' format string with unnamed arguments cannot be properly localized
并且无法为此事项生成语言文件.
有没有办法绕过这个错误?
更新
我遇到过这种绕过错误而不改变数据库的方法.在数据库中,级别要求以dict格式存储在文本字段中:
#Requirment of Runner's badge
"{'gold':(100,10),'silver':(50,5),'bronze':(25,2)}"
Run Code Online (Sandbox Code Playgroud)
在类定义中,手动将参数名称添加为'arg_0','arg_1'...到描述中.在用于填充描述字符串之前,将get_description方法更改为预处理数据.
class RunnersBadge(Badge):
requirements=#get the previous dict from database
description="You get this badge because you've runned %(arg_0)d meters in %(arg_1)d minutes"
@classmethod
def get_description(cls,level):
'''
This is actually a method of parent class Badge
level is either 'gold','silver' or 'bronze'
'''
dic={}
try:
for (num,val) in enumerate(cls.requirements[level]):
dic['arg_'+str(num)]=val
except TypeError:
dic['arg_0']=cls.requirements[level]
return cls.description%dic
Run Code Online (Sandbox Code Playgroud)
此方法保留了大部分当前结构(逻辑和数据库).译者只需要处理"放置"这几个字.
就像在代码中一样,变量名在其上下文中应该是有意义的,'meter_count'和'minute_count'是显式的,与'arg_0'和'arg_1'相比是无意义的
在python代码中使用标准转换,它不易出错,并且被令人惊讶的makemessages命令识别
使用使用命名字符串插值(例如,%(day)s
),而不是位置的内插(例如,%s
或%d
),只要你有超过一个参数更多,因为参数的顺序可以根据语言的变化.即德语和拉丁语反转名词/形容词顺序,日期根据语言等不同显示...
使用run而不是runned,仔细检查你的英文翻译字符串的语法有效性
这个:
class RunnersBadge(Badge):
requirements=#get the previous dict from database
description="You get this badge because you've runned %(arg_0)d meters in %(arg_1)d minutes"
Run Code Online (Sandbox Code Playgroud)
变为:
from django.utils.translation import ugettext as _
class RunnersBadge(Badge):
requirements=#get the previous dict from database
description=_("You get this badge because you've ran %(meter_count)d meters in %(minute_count)d minutes")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1855 次 |
最近记录: |