Agata S. Agata S. - 3 months ago 16
HTML Question

Flask forms not working

I just started learning Flask, and as a practice project I wanted to build a simple site that asks the user for their name, and greets them by their name on a new page. I have been unable to get a user's name through a form, and display it on a new page due to to a 'Bad Request' error. My code is below.

This is my index page with the form on it:

<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<h1>Practice index page</h1>
<h2>Welcome to my practice web page.</h2>

<form action = "/firstname">
<p>What's your name?</p>
<input type = "text" name = "yourname"><br>
<input type = "submit" value = "Submit">
</form>
</body>
</html>


This is my application.py file:

from flask import Flask
from flask import render_template, request, redirect
app = Flask(__name__)

@app.route('/')
def hello_world():
return render_template('index.html')

@app.route('/firstname')
def first_name():
yourname = request.form['yourname']
return render_template('firstname.html', name = yourname)


And this is my firstname.html file:

<!DOCTYPE html>
<head>
<title>My name is</title>
</head>
<body>
<h1>Hello</h1>
<h2>Your name is {{name}}.</h2>
</body>


The index page loads fine. The firstname.html template also loads fine when the user's name is hardcoded, it's only when I get it from the form that problems arise.

I have been at this for a few hours, watched YT videos, Googled like crazy, and still can't figure out what's wrong, so I would really appreciate some help!

Answer Source

By default, a Flask route only answers to GET requests. You can tell the first_name view to answer both GET and POST requests like so:

@app.route('/firstname', methods=['GET', 'POST'])
def first_name():
    yourname = request.form['yourname']
    return render_template('firstname.html', name = yourname)

You also need to set the form method to POST so that yourname is sent as form data (readable in request.form) and not as a URL parameter (readable in request.args).

<form action = "/firstname" method="POST">
    <p>What's your name?</p>
    <input type = "text" name = "yourname"><br>
    <input type = "submit" value = "Submit">
</form>