Django表单初始化问题-如何在超类中设置本地化?

时间:2018-08-25 10:56:29

标签: django django-forms localization initialization

我有一个模型表单,其中根据用户的语言环境混合英制和度量单位(例如m / s和fps),因此该表单是使用手动添加的表单字段并引用模型的混合。

现在,我们以多种形式执行此操作,因此创建了一个超类LocalizedModel形式,该形式仅对子类字段进行迭代,如果为十进制,则为所有字段设置localized = True。

预期结果是在模板中生成表单时;所有十进制字段都应本地化(或。),并使用文本输入而不是数字。

奇怪的是,

  • 当使用遍历字段并设置事物的超类时,表单未本地化,并且仍使用数字输入。

但是

  • 直接在字段中设置localize = True时有效(正确设置了文本和小数点分隔符)

Python 3和Django 2.0.6以及USE_L10N为True。

知道为什么会这样吗?

请参见下面的代码段

 # -- example -- 
class RecipeForm(LocalizedModelForm):

    cost = forms.DecimalField(label='Cost', initial=0, min_value=0, localize=True)
    cost_2 = forms.DecimalField(label='Other Costs', initial=0, min_value=0)

    # cost has manually set - works in template
    # cost_2 and weight - expected that LocalizedModel for should set them, but no

    class Meta:
        model = Recipe   
        fields = [
            'cost',
            'cost_2',
            'weight', 
        ]

    def __init__(self, *args, **kwargs):
        super(RecipeForm, self).__init__(*args, **kwargs)

# ---------------------------------------------------------
class LocalizedModelForm(django.forms.ModelForm):

    def __new__(cls, *args, **kwargs):
        new_class = super(LocalizedModelForm, cls).__new__(cls)

        for field in list(new_class.base_fields.values()):
            if isinstance(field, django.forms.DecimalField):
                field.localize = True
                field.widget.is_localized = True

    return new_class

1 个答案:

答案 0 :(得分:1)

您正在更改字段属性,因为它已经被初始化,这基本上意味着该字段自从没有NumberInput属性被初始化以来已经呈现了localize小部件。

解决方案是使用适当的参数调用字段的__init__方法以重新初始化对象。

或者,查看类IntegerFieldDecimalField的超类)__init__方法,可以看到如果localizeTrue和{{1 }}是widget,那么它将始终将超类NumberInput的小部件设置为Field

解决方案

TextInput