bhoward
bhoward

Reputation: 2890

validate_on_submit always returns false using Flask WTForms

I have a simple radio field, and it always causes validate_on_submit to return false. When I print form.errors, it looks like "not a valid choice" is being passed as the value from the radio field, despite coerce=int.

I don't think I'm clobbering anything returned in the forms, and I'm hopefully creating dynamic choices the right way. I don't understand why this fails.

Here are the relevant parts of my project - any suggestions appreciated.

forms.py:

class SelectRecord(Form):
    rid = RadioField("Record Select", choices=[], coerce=int,validators=[InputRequired()])

views.py:

@mod.route('/select/', methods=('GET', 'POST'))
@login_required
def select_view():
    form = SelectRecord(request.form)
    if form.validate_on_submit():
        rid = form.data.rid
        if form['btn'] == "checkout":
            # check out the requested record
            Records.checkoutRecord(rid)
            return render_template('/records/edit.html',rid=rid)
        elif form['btn'] == "checkin":
            Records.checkinRecord(rid)
            flash("Record checked in.")
    else:
        mychoices = []
        recs_co = session.query(Records.id).filter(Records.editing_uid == current_user.id).  \
            filter(Records.locked == True)
        for x in recs_co:
            mychoices.append((x.rid,"%s: %s (%s)" % (x.a, x.b, x.c, x.d)))
        x = getNextRecord()
        mychoices.append((x.id,"%s: %s (%s %s)" % (x.a, x.b, x.c, x.d)))
        form.rid.choices = mychoices
    print form.errors
    return render_template('records/select.html', form=form)

And my template (select.html):

<form method="POST" action="/select/" class="form form-horizontal" name="select_view">
        <h1>Select a record to edit:</h1>
        {{ render_field(form.rid, class="form-control") }}
        {{ form.hidden_tag() }}
        <button type="submit" name="btn" class="btn" value="Check Out">Check Out</button>
        <button type="submit" name="btn" class="btn" value="Check In">Check In</button>
    </form>

Upvotes: 4

Views: 7208

Answers (1)

Mark Hildreth
Mark Hildreth

Reputation: 43131

You have your field that looks like this...

rid = RadioField("Record Select", choices=[], coerce=int,validators=[InputRequired()])

Note that you left choices as an empty list. You're basically saying, "there are no choices that would be valid for this field". If WTForms thinks there aren't any choices to pick from, the choices that you do use will always be invalid.

Now, it looks like you are TRYING to add those choices down below in your else statement...

form.rid.choices = mychoices

At the time that this is running, you'll be able to correctly render the form (which happens at the end of your method). However, the timing is such that the choices are given to the form object too late to be used as part of the validation, since that happens near the top of the method in validate_on_submit()!

Try to take the code you'r using to fill form.rid.choices and have it run BEFORE you do validate_on_submit.

Upvotes: 8

Related Questions