Apply Now Apply Now Apply Now
header_logo
Post thumbnail
PROGRAMMING LANGUAGES

How to Create an HTML Form in Flask (2026 Step-by-Step Guide)

By Abhishek Pati

To create a basic HTML form in Flask, you build the form in an HTML file, then use a Flask route to read and process what the user submits. That’s the whole idea in one line, but getting it working properly and doing it the right way takes a few more steps.

In this guide, you’ll set up a simple Flask project, create an HTML form, and handle the submitted data using Python. We’ll also cover the parts most tutorials skip, like validating input and protecting your form with CSRF security, so what you build here isn’t just a toy example but something closer to how forms are actually handled in real projects.

Table of contents


  1. TL;DR Summary
  2. What You'll Need Before You Start
  3. Setting Up Your Flask Project Structure
  4. Creating an HTML Form in Flask
  5. Handling Form Data in Flask (GET vs POST)
  6. Displaying Submitted Data on Another Page
  7. Adding Server-Side Validation
  8. Securing Your HTML Form in Flask with CSRF Protection
  9. Common Mistakes to Avoid
  10. Conclusion
  11. FAQs
    • How do I create a form in HTML Flask?
    • How to get form data in Flask?
    • Is GET or POST used for forms in Flask?
    • How do I display form data in Flask?
    • Do I need Flask-WTF to build an HTML form in Flask?

TL;DR Summary

  • Flask forms work by connecting an HTML file to a Python route, the form sends data, Flask reads it, and does something with it
  • You’ll use render_template() to show the form and request.form to grab what the user typed in
  • GET and POST aren’t interchangeable here, POST is what you want when a form is actually submitting data
  • Skipping server-side validation is one of the most common mistakes, client-side checks alone aren’t enough
  • For anything beyond a quick test, Flask-WTF and CSRF protection turn a basic form into something actually safe to use

💡 Did You Know?

Flask was first released by Armin Ronacher on April 1, 2010, and despite its April Fools’ Day launch, it became one of Python’s most widely used web frameworks.

What You’ll Need Before You Start

Before jumping in, make sure you have Python installed on your system, along with a code editor like VS Code. You’ll also need Flask itself, which you can install using pip:

pip install Flask

A basic understanding of Python and HTML helps, but you don’t need to be an expert. If you know how variables and functions work in Python, and how a basic HTML page is structured, you’re ready to go.

Full stack development starts with small, practical wins like this one, and builds into something much bigger. HCL GUVI’s Software & AI Engineer Course takes you through the full stack, from React and JavaScript on the frontend to Node.js, Express, and MongoDB on the backend, along with APIs, authentication, and real deployment workflows. Enroll today and start building the skills top tech companies are actually hiring for!

Setting Up Your Flask Project Structure

Flask expects a specific folder layout to find your HTML files correctly. Create a project folder, and inside it, set up your files like this:

my_flask_form/
│
├── app.py
└── templates/
    └── form.html

The templates folder isn’t optional, Flask looks for HTML files there by default when you use render_template(). If your HTML file sits outside this folder, Flask won’t find it, and you’ll run into an error.

Creating an HTML Form in Flask

Now let’s build the actual HTML form in Flask. Inside templates/form.html, add the following:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Simple Form</title>
</head>
<body>
    <h2>Enter Your Details</h2>
    <form action="/submit" method="POST">
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" required>
        <br><br>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" required>
        <br><br>
        <button type="submit">Submit</button>
    </form>
</body>
</html>

Here’s what’s happening in this code. The <form> tag has an action attribute set to /submit, which tells the browser where to send the data once the user hits submit.

The method="POST" means the data is sent securely in the request body rather than exposed in the URL. Each <input> field has a name attribute, this is important, because that’s exactly how Flask will identify and retrieve each piece of data on the backend.

Want to go beyond a single form? HCL GUVI’s Web Development with Python Flask Course covers Flask routing, templating, user authentication, database integration, and building REST APIs, everything needed to build real Flask applications, not just basic examples.

Handling Form Data in Flask (GET vs POST)

With the HTML form ready, you now need a Flask route to display it and another to handle what’s submitted. Open app.py and add this:

from flask import Flask, render_template, request

app = Flask(__name__)

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

@app.route('/submit', methods=['POST'])
def submit():
    name = request.form['name']
    email = request.form['email']
    return f"Thanks, {name}! We received your email: {email}"

if __name__ == '__main__':
    app.run(debug=True)

The first route simply renders the form when someone visits the homepage. The second route, /submit, only accepts POST requests, which matches the method we set in the HTML form. Inside this route, request.form['name'] and request.form['email'] pull the actual values the user typed in, using the same name attributes defined in the HTML.

It’s worth understanding why POST matters here. GET requests append data to the URL, which isn’t suitable for anything sensitive, like passwords or personal details. POST keeps that data inside the request body, out of the URL entirely, making it the correct choice for form submissions.

Displaying Submitted Data on Another Page

Right now, the submitted data just shows up as plain text. A cleaner approach is to render it on a separate HTML page. Create a new file, templates/result.html:

GUVI Ad
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Submission Result</title>
</head>
<body>
    <h2>Thank you, {{ name }}!</h2>
    <p>We've received your email: {{ email }}</p>
</body>
</html>

Then update the /submit route in app.py to render this page instead of returning plain text:

@app.route('/submit', methods=['POST'])
def submit():
    name = request.form['name']
    email = request.form['email']
    return render_template('result.html', name=name, email=email)

Important Note:

Notice the double curly braces in result.html, like {{ name }}. This is Jinja2 syntax, Flask’s built-in templating engine, and it’s how Python variables get inserted directly into your HTML.

Adding Server-Side Validation

Client-side validation, like the required attribute in your HTML input, is helpful, but it can be bypassed easily. Anyone can disable JavaScript or send a request directly, skipping your form entirely. That’s why server-side validation matters.

Here’s a simple way to add it:

@app.route('/submit', methods=['POST'])
def submit():
    name = request.form.get('name', '').strip()
    email = request.form.get('email', '').strip()

    if not name or not email:
        return "Name and email are required.", 400

    return render_template('result.html', name=name, email=email)

Using .get() instead of direct dictionary access avoids errors if a field is missing entirely, and the check right after makes sure empty submissions don’t slip through. This small addition makes your form noticeably more reliable.

Securing Your HTML Form in Flask with CSRF Protection

This is the part most beginner tutorials skip entirely, but it matters a lot once your form handles real user data. Without protection, your form can be vulnerable to CSRF (Cross-Site Request Forgery) attacks, where a malicious site tricks a user’s browser into submitting a form on your site without their knowledge.

The standard way to fix this in Flask is using Flask-WTF, an extension that adds CSRF protection automatically. First, install it:

pip install flask-wtf

Then update app.py to include a secret key, which Flask-WTF needs to generate CSRF tokens:

app.config['SECRET_KEY'] = 'your-secret-key-here'

And in your HTML form, add a hidden CSRF token field:

<form action="/submit" method="POST">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
    ...
</form>

This token gets validated automatically on submission, and if it’s missing or doesn’t match, Flask-WTF blocks the request. It’s a small addition, but it’s the difference between a form that works and a form that’s actually safe to use in production.

GUVI Ad

Common Mistakes to Avoid

A few mistakes come up repeatedly when people are just starting out with an HTML form in Flask:

  1. Forgetting the name attribute: Without it, request.form has no way to identify the field, and you’ll get a KeyError.
  2. Mismatched form method: If your HTML form uses POST but your Flask route only allows GET, Flask will return a 405 error.
  3. Placing HTML files outside the templates folder: render_template() won’t find your file, and you’ll get a TemplateNotFound error.
  4. Skipping server-side validation: Relying only on HTML’s required attribute leaves your form open to bad or missing data.
  5. Ignoring CSRF protection: Fine for practice projects, but a real risk once your form is live and handling actual user input.

Conclusion

Building an HTML form in Flask starts simple, an HTML file, a route, and a bit of Python to read what’s submitted. But going from a working example to something production-ready means adding validation and CSRF protection along the way. Once you’ve built one form this way, the same pattern applies to pretty much any form you’ll build in Flask going forward, login pages, contact forms, feedback systems, all of it.

FAQs

1. How do I create a form in HTML Flask?

Build the form in an HTML file inside the templates folder, then render it using render_template() in your Flask route. This is how you create a html form in flask.

2. How to get form data in Flask?

Use request.form['field_name'] inside your route to access whatever the user typed into that input field.

3. Is GET or POST used for forms in Flask?

POST is used for form submissions since it keeps data in the request body instead of exposing it in the URL.

4. How do I display form data in Flask?

Pass the submitted data into render_template() and use Jinja2’s {{ }} syntax to show it on another page.

5. Do I need Flask-WTF to build an HTML form in Flask?

No, it’s optional for basic forms, but recommended for CSRF protection and validation in production.

Success Stories

Did you enjoy this article?

Learn with HCL GUVI

Schedule 1:1 free counselling

Similar Articles

Loading...
Get in Touch
Chat on Whatsapp
Request Callback
Share logo Copy link
Table of contents Table of contents
Table of contents Articles
Close button

  1. TL;DR Summary
  2. What You'll Need Before You Start
  3. Setting Up Your Flask Project Structure
  4. Creating an HTML Form in Flask
  5. Handling Form Data in Flask (GET vs POST)
  6. Displaying Submitted Data on Another Page
  7. Adding Server-Side Validation
  8. Securing Your HTML Form in Flask with CSRF Protection
  9. Common Mistakes to Avoid
  10. Conclusion
  11. FAQs
    • How do I create a form in HTML Flask?
    • How to get form data in Flask?
    • Is GET or POST used for forms in Flask?
    • How do I display form data in Flask?
    • Do I need Flask-WTF to build an HTML form in Flask?