简体   繁体   中英

Can I set a StringField's default value outside the field constructor?

If I set the default value during construction of the field, all works as expected:

my_field = StringField("My Field: ", default="default value", validators=[Optional(), Length(0, 255)])

However, if I try to set it programmatically, it has no effect. I've tried by modifying the __init__ method like so:

class MyForm(FlaskForm):
    my_field = StringField("My Field: ", validators=[Optional(), Length(0, 255)])

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.my_field.default = "set default from init"  # doesn't work

This does not set the default value. How can I do this programatically (because the value is dynamic based on a database query, and if I do this outside of __init__ then it does not get the most current value)?

Relevant versions from my requirements.txt :

Flask==0.12
Flask-WTF==0.14.2
WTForms==2.1

Also, I'm running Python 3.6 if that matters.

Alternatively, I'm fine with a solution that enables me to set the value data for this field on initial form load when adding a new record (same behavior as default value being specified in constructor) but this same form is also used for editing so I would not want it changing object data that is already saved/stored on edit.

You can set initial values for fields by passing a MultiDict as FlaskForm 's formdata argument.

from werkzeug.datastructures import MultiDict

class MyForm(FlaskForm):
    my_field = StringField("My Field: ", validators=[Optional(), Length(0, 255)])


form = MyForm(formdata=MultiDict({'my_field': 'Foo}))

This will set the value of the my_field input to 'Foo' when the form is rendered, overriding the default value for the field. However you don't want to override the values when the form is posted back to the server, so you need to check the request method in your handler:

from flask import render_template, request
from werkzeug.datastructures import MultiDict

@app.route('/', methods=['GET', 'POST'])
def test():
    if request.method == 'GET':
        form = MyForm(formdata=MultiDict({'my_field': 'Foo'}))
    else:
        form = MyForm()
    if form.validate_on_submit():
        # do stuff
    return render_template(template, form=form)

You can access your fields in __init__ as a dictionary:

class MyForm(FlaskForm):

  def __init__(self, *args, **kwargs):
     default_value = kwargs.pop('default_value')
     super(MyForm, self).__init__(*args, **kwargs)
     self['my_field'] = StringField("My Field: ", default=default_value,
                                    validators=[Optional(), Length(0, 255)])

You would then call it like this:

form = MyForm(default_value='Foo')

See the documentation for the wtforms.form.Form class for more information and other details.

its to late to reply on this question but I saw a simple way to do this which is not mentioned in answers above. Simplest way to asign a value is

@app.route('/xyz', methods=['GET', 'POST'])
def methodName():
    form = MyForm()
    form.field.data = <default_value>
    .....
    return render_template('abc.html', form=form)

The field of the form will display asigned default_value when page load.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM