mathmagician
mathmagician

Reputation: 55

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!

Upvotes: 2

Views: 4823

Answers (3)

Bovarysme
Bovarysme

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

Sunny Aggarwal
Sunny Aggarwal

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

Kishan Mehta
Kishan Mehta

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

Related Questions