Dynamic Flask-Form construction intended for use under Jinja

亡梦爱人 提交于 2019-12-11 23:27:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!