我有表格:
class UserForm(forms.Form):
fname = forms.CharField(max_length=30, label=_('First Name'), validators=[Alpha()])
lname = forms.CharField(max_length=30, label=_('Last Name {name}').format(name='XXXX'), validators=[Beta()])
我正在使用 form.as_p 呈现此表单,当我更改我的语言名字被翻译但由于某种原因姓氏{name} 使用格式化方法进行字符串插值未翻译,此字符串的翻译也出现在语言目录中。我在Django 1.8和python 2.7上。
更新 似乎由于某些原因,django没有在我的表单中对插值字符串进行惰性求值,它在服务器启动后的第一个请求中调用ugettext_lazy用于插值字符串,并且在实际获取时不会对该字符串进行求值。
答案 0 :(得分:0)
非常古老的问题,但今天它让我感到困惑,所以这是我的答案:%
运算符在表单初始化时立即执行(即在服务器启动时),因此 label
不再是代理,并且变成一个字符串,这显然打破了翻译机制。
顺便说一句,据我所知,即使您使用 .format()
而不是插值运算符,这也适用,因为该函数的返回仍然是纯字符串而不是代理。
至于解决方案:如果你只需要在几个表单字段中使用插值,简单的方法是在__init__()
中设置标签,如下所示:
class MyForm(forms.Form):
myfield = forms.BooleanField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['myfield'].label = _("Your interpolated %(value)s") % {'value': 'field'}
如果您需要很多字段,更好的解决方案是创建一个接受新 label_mapping
kwarg 的自定义字段(或多个,使用 mixin),例如:
class MyCustomField(Field):
def __init__(label_mapping=None, label=None, *args, **kwargs):
if label is not None and label_mapping is not None:
label = label % label_mapping
super().__init__(label=label, *args, **kwargs)
在我看来,除了删除样板代码之外,这样做的主要优点是保留表单字段的声明性语法。
请注意,我只有几个字段需要注意,所以我实际上并没有使用自定义字段类方法,但我不明白为什么它不应该起作用(经过适当的测试)。