问题
My purpose is to construct a form with dynamicly provided labels and use it in Jinja Form. This made me reveal multiple fundemental questions. As in the exemple here
from flask_wtf import FlaskForm
from wtforms import SubmitField
from wtforms.validators import DataRequired
class LoginForm(FlaskForm):
# submit = SubmitField('Go On')
def __init__(self, BtnLble):
self.submit = SubmitField(BtnLble,form=self, name="MySbmt", _meta=self.Meta)
# self.submit.bind(form=self, name="MySbmt", _meta=self.Meta)
super(LoginForm,self).__init__()
self.submit() # .__call__() does not exist
def UseForm( ) :
Login = LoginForm(“Hit here”)
if form.validate_on_submit():
flash('Wellcom... ' )
return redirect(url_for(‘GoOn’))
return render_template('Login.html', **locals())
I try to construct my form ‘dynamically’ in the __init __ part of the form class. It seems that the construction of elements (put in comment in the example) differs from that one done in the declaration part
In the above example, the call “submit()” will result with ‘Non callable object’. While it will be possible if only it is declared in declaration part ! So the following questions become to mind :
1) What is the difference between declaration in the declaration part and the one done inside __init __'. We are not using a ‘static’ variable her!
2) How to make a ‘field of a Form’ callable ?
3) It seems that the callability becomes to exist only after the call of the FlaskForm’s initiator. How does it add ‘a method’ to this object ?
I noticed that similar questions have been revealed by other experienced developers, but they did not provided them in such simple way, like this one
WTForms keeps giving "Not Callable" error during server run, but not on the python prompt
回答1:
The fields in a wtforms.Form
class are set up by the wtforms.forms.FormMeta
metaclass. By the time a form instance's __init__
method is called it's too late to add a new field to the form.
You could modify your form class dynamically, as described in the documentation. Note that this will affect all future instances of the class.
setattr(LoginForm, 'submit', wtforms.SubmitField('Hit here'))
form = LoginForm()
If you only want to customise the label for a field in a particular instance, you can do this in the instance's __init__
method.
class LoginForm(wtforms.Form):
submit = wtforms.SubmitField()
def __init__(self, label, **kwargs):
super().__init__()
self.submit.label = wtforms.Label(self.submit.id, label)
来源:https://stackoverflow.com/questions/51095704/dynamic-flask-form-construction-intended-for-use-under-jinja