Flask view shows 400 error instead of template with form

Your view accepts GET and POST requests. request.form is only filled out on POST. If you try to access a key that doesn’t exist, it raises a 400 error. No keys will exist when you GET the page initially.

The common pattern for this is to guard code that requires request.form in an if request.method == 'POST' block. Return a redirect after handling the POST request, otherwise return the rendered template.

from flask import url_for, redirect, render_template

@app.route('/addplayer', methods=['GET', 'POST'])
def addplayer():
    if request.method == 'POST':
        Post(
            name=request.form['name'],
            available=request.form['available']
        ).save()
        return redirect(url_for('index'))

    return render_template('addplayer.html')

Since you appear to be using Flask-WTF, you can use the form’s validate_on_submit method instead of checking method. In that case, you can also access the data through the form instance, and use the form to render the inputs for you.

from flask import url_for, redirect, render_template

@app.route('/addplayer', methods=['GET', 'POST'])
def addplayer():
    form = AddPlayerForm()

    if form.validate_on_submit():
        Post(
            name=form.name.data,
            available=form.available.data
        ).save()
        return redirect(url_for('index'))

    return render_template('addplayer.html', form=form)
<form method=post>
    {{ form.hidden_tag() }}
    {{ form.name.label}} {{ form.name }}<br>
    {{ form.available.label }} {{ form.available }}<br>
    <input type=submit value="Add Player">
</form>

Leave a Comment