Skip to content

Handling Form Data

HTML forms usually submit data using POST with a content type like:

  • application/x-www-form-urlencoded
  • multipart/form-data (required for file uploads)
diagram POST then redirect then GET, and why the redirect is not optional mermaid
If a POST responds with HTML directly, the browser remembers the POST. Reloading that page re-submits the form, and the back button offers to do it again -- so the order is placed twice. Answering with a redirect means the address the browser ends up on is a plain GET, which is safe to reload and safe to bookmark.

Template templates/contact.html:

html
<form method="post">
  <input type="text" name="name" placeholder="Your name" />
  <input type="email" name="email" placeholder="Email" />
  <button type="submit">Send</button>
</form>

Route:

python
from flask import Flask, request, render_template
 
app = Flask(__name__)
 
 
@app.route("/contact", methods=["GET", "POST"])
def contact():
    if request.method == "POST":
        name = request.form.get("name", "")
        email = request.form.get("email", "")
 
        # TODO: validate input here
        return f"Thanks {name}, we received {email}!"
 
    return render_template("contact.html")
  • Missing methods=["GET", "POST"] → POST returns 405
  • Forgetting to validate user input
  • Returning a success page directly after POST (refresh resubmits)

After a successful POST:

  • save/process data
  • redirect() to a GET route

This prevents double submission on refresh.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading