I’m trying to display a page with a form, then add a Player to the database when the form is submitted. However, I can’t view the form because the browser always shows a 400 Bad Request error. Other posts indicate that this could be because the name of the form input doesn’t match the key I get from request.form, but all my keys match. Why do I get this error?
<form method="post">
{{ form.hidden_tag() }}
<input name="name">
<input name="available">
<input type="submit">
</form>
@app.route('/addplayer', methods=['GET', 'POST'])
def addplayer():
connect('basketball_contracts', host='localhost', port=27017)
n = request.form['name']
a = request.form['available']
post= Post(
name=n,
available=a
)
post.tags = ['test']
post.save()
return render_template('addplayer.html', form=form)
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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>
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0