I know I can create dynamic fields like this: http://wtforms.simplecodes.com/docs/1.0.1/specific_problems.html#dynamic-form-composition
But the above solution is unwieldy in my case, and requires a special API which I would like to avoid. I am wondering if there is a way to get this working with multiple inheritance? I tried the following and it won't work and I don't know why, I figured that WTForms should bind the forms properly given how the class structure is working:
>>> 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}
As you can see the dynamic_boolean is unbound. How can I set this up so that the dynamic_boolean field is bound properly?
WTForms uses a metaclass to handle binding at instantiation time. This metaclass does its work before Form.__init__
is called, thus making it not possible for something in __init__
to create a field that's bound.
The way WTForms is designed is done so as to reduce the amount of work to be done in searching for and finding field classes to only happen the first time a form is instantiated, speeding up your application after the initial request.
Alternately If you're willing to put in the legwork, it is possible to design something similar to Form that supports this behavior, based on BaseForm and using your own metaclass. Be warned, BaseForm is not the same thing as Form, it's purely a low-level way designed for authors of complementary libraries to get access to build similar tools.
来源:https://stackoverflow.com/questions/23594448/wtforms-adding-dynamic-fields-with-multiple-inheritance