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





Dynamic labels example
– snakecharmerb
Jun 30 at 5:35




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.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV