Reputation: 55
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!
Upvotes: 2
Views: 4823
Reputation: 453
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>
Upvotes: 2
Reputation: 81
Use request.args['yourname']
instead of request.form['yourname']
Your index.html form is calling /firstname url with get method and name argument as query string
GET /firstname?yourname=Sunny HTTP/1.1
so you need to access query parameters with request.args['yourname'] & not with request.form['yourname']
Upvotes: 1
Reputation: 2678
You need to pass variables as dict and not directly.
Like this
@app.route('/firstname')
def first_name():
yourname = request.form['yourname']
return render_template('firstname.html', **{"name": "yourname"})
Upvotes: 0