Dynamic Flask-Form construction intended for use under Jinja
Dynamic Flask-Form construction intended for use under Jinja
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 Answer
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.
wtforms.Form
wtforms.forms.FormMeta
__init__
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.
__init__
class LoginForm(wtforms.Form):
submit = wtforms.SubmitField()
def __init__(self, label, **kwargs):
super().__init__()
self.submit.label = wtforms.Label(self.submit.id, label)
The second piece of code was perfect to solve my problem, many thanks. Thus, I can continue my multi-languages easy form model.
– Farazdak
2 days ago
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Dynamic labels example
– snakecharmerb
Jun 30 at 5:35