Wtforms:使用多重继承添加动态字段

6 投票
1 回答
2352 浏览
提问于 2025-04-18 06:12

我知道可以像这样创建动态字段:http://wtforms.simplecodes.com/docs/1.0.1/specific_problems.html#dynamic-form-composition

不过,上面的解决方案在我的情况下有点麻烦,而且需要一个我想避免的特殊接口。我在想有没有办法用多重继承来实现这个功能?我试了以下代码,但它不工作,我也不知道为什么。我觉得根据类的结构,WTForms应该能正确绑定这些表单:

>>> class Base(Form):
...     def __init__(self, **kwargs):
...         setattr(self, 'dynamic_boolean', fields.BooleanField('label'))
...         super(Base, self).__init__(**kwargs)
... 
>>> class Inherit(Base):
...     other_boolean = fields.BooleanField('label')
... 
>>> 
>>> form = Inherit()
>>> form.__dict__
{'dynamic_boolean': <UnboundField(BooleanField, ('label',), {})>, 'other_boolean': <wtforms.fields.core.BooleanField object at 0x8a8510c>, '_fields': {'other_boolean': <wtforms.fields.core.BooleanField object at 0x8a8510c>}, '_prefix': '', '_errors': None}

如你所见,dynamic_boolean字段没有被绑定。那我该怎么设置才能让dynamic_boolean字段正确绑定呢?

1 个回答

8

WTForms使用了一种叫做元类的东西来处理表单创建时的绑定。这种元类在调用Form.__init__之前就开始工作,所以在__init__里面的代码无法创建已经绑定的字段。

WTForms的设计是为了减少在第一次创建表单时查找和找到字段类所需的工作量,这样可以加快你应用程序在初次请求后的速度。


另外,如果你愿意花时间去研究,可以设计一个类似于Form的东西,支持这种行为,基于BaseForm并使用你自己的元类。不过要注意,BaseForm和Form并不是同一个东西,BaseForm只是一个低级的方式,专门为那些想要创建类似工具的库作者提供的。

撰写回答