Django表单初始化问题-如何在超类中设置本地化?
我有一个模型表单,其中我根据用户的区域设置混合使用英制和公制单位(例如m/s和fps),因此该表单是使用手动添加的表单字段和引用模型的组合 现在,我们在许多表单中执行此操作,因此创建了一个超级类LocalizedModel表单,它只需在子类字段上迭代,如果是decimal,则为所有字段设置localized=True 预期结果是在模板中生成表单时;所有十进制字段都应本地化(、或),并使用文本输入,而不是数字 奇怪的是,Django表单初始化问题-如何在超类中设置本地化?,django,django-forms,localization,initialization,Django,Django Forms,Localization,Initialization,我有一个模型表单,其中我根据用户的区域设置混合使用英制和公制单位(例如m/s和fps),因此该表单是使用手动添加的表单字段和引用模型的组合 现在,我们在许多表单中执行此操作,因此创建了一个超级类LocalizedModel表单,它只需在子类字段上迭代,如果是decimal,则为所有字段设置localized=True 预期结果是在模板中生成表单时;所有十进制字段都应本地化(、或),并使用文本输入,而不是数字 奇怪的是, 当使用在字段上迭代并设置内容的超类时,表单没有本地化,仍然使用数字输入
- 当使用在字段上迭代并设置内容的超类时,表单没有本地化,仍然使用数字输入李>
- 直接在字段中设置localize=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
在字段属性初始化之后,您正在更改它,这基本上意味着该字段已经呈现了
NumberInput
小部件,因为它是在没有localize
属性的情况下初始化的
解决方案是使用正确的参数调用字段的\uuuu init\uuu
方法来重新初始化对象
或者,查看classIntegerField
(DecimalField的超类)方法,您可以看到如果localize
是True
,并且widget
是NumberInput
,那么它将始终将超类字段的widget设置为TextInput
解决方案:
from django.forms.widgets import TextInput
def __new__(cls, *args, **kwargs):
new_class = super(LocalizedModelForm, cls).__new__(cls)
# keep the same reference to the field, change to `items`.
for field_name, field in new_class.base_fields.items():
if isinstance(field, django.forms.DecimalField):
widget = TextInput()
extra_attrs = field.widget_attrs(widget)
if extra_attrs:
widget.attrs.update(extra_attrs)
field.widget = widget
return new_class
谢谢,我对事物初始化的顺序有一种感觉,这为我解决了它:-)