Web Form with Validation in Python
About the project: This is a project for a self-contained web form with server-side validation using Python and the Flask framework, along with the Flask-WTF library for simplified form handling.
- This project uses a single file to demonstrate how to:
- Create a web form with a GET route.
- Handle form submission and validation with a POST route.
- Display validation error messages to the user.
To make the project a single file, the HTML template is embedded directly into the Python code as a string.
How to Run the App
- Install Libraries: This project requires Flask and Flask-WTF. You'll need to install them first using `pip`.
Note: Flask-WTF will automatically install WTForms as a dependency.pip install Flask Flask-WTF
- Save the Code:Save the code above as a file named `web_form_app.py`.
- Run from Terminal: Open your terminal or command prompt, navigate to the directory where you saved the file, and run the script:
python web_form_app.py
- Access the Form: Open your web browser and go to http://127.0.0.1:5000.
The app will display a registration form. You can test the validation by leaving fields blank, entering an invalid email, or providing a password that doesn't match the confirmation. If the form passes validation, it will display a success message.
Project Level: Intermediate
You can directly copy the below snippet code with the help of green copy button, paste it and run it in any Python editor you have.
Steps: Follow these stepsStep 1: Copy below code using green 'copy' button.
Step 2: Paste the code on your chosen editor.
Step 3: Save the code with filename and .py extention.
Step 4: Run (Press F5 if using python IDLE).
# web_form_app.py
from flask import Flask, render_template_string, request, flash, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, EmailField, SubmitField
from wtforms.validators import DataRequired, Email, EqualTo, Length
# Initialize the Flask application
app = Flask(__name__)
# A secret key is required for Flask-WTF to protect against CSRF attacks.
# Change this to a random value in a real-world application.
app.config['SECRET_KEY'] = 'your-secret-key-that-should-be-random-and-long'
# --- Define the Web Form ---
# This class defines the fields and validation rules for our registration form.
class RegistrationForm(FlaskForm):
"""
A simple registration form with fields for a username, email, and password.
Validators ensure the data is present and correctly formatted.
"""
username = StringField(
'Username',
validators=[DataRequired(), Length(min=4, max=25)]
)
email = EmailField(
'Email',
validators=[DataRequired(), Email()]
)
password = PasswordField(
'Password',
validators=[DataRequired(), Length(min=8)]
)
confirm_password = PasswordField(
'Confirm Password',
validators=[DataRequired(), EqualTo('password')]
)
submit = SubmitField('Register')
# --- HTML Template as a Python string ---
# This template is embedded directly in the Python file for simplicity.
# It displays the form and any validation errors.
HTML_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration Form</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background-color: #fff;
padding: 20px 40px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 400px;
}
h2 {
text-align: center;
color: #333;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="text"],
input[type="email"],
input[type="password"] {
width: 100%;
padding: 10px;
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 4px;
}
.error {
color: #d9534f;
font-size: 0.9em;
margin-top: 5px;
}
input[type="submit"] {
width: 100%;
padding: 10px;
background-color: #5cb85c;
border: none;
color: white;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s;
}
input[type="submit"]:hover {
background-color: #4cae4c;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
ul li {
background-color: #f2dede;
color: #a94442;
padding: 10px;
border: 1px solid #ebccd1;
border-radius: 4px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="container">
<h2>Register</h2>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form method="POST" action="{{ url_for('register') }}" novalidate>
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.username.label }}
{{ form.username() }}
{% for error in form.username.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.email.label }}
{{ form.email() }}
{% for error in form.email.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password() }}
{% for error in form.password.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.confirm_password.label }}
{{ form.confirm_password() }}
{% for error in form.confirm_password.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
</div>
<div class="form-group">
{{ form.submit() }}
</div>
</form>
</div>
</body>
</html>
"""
# --- Flask Routes ---
@app.route('/', methods=['GET', 'POST'])
def register():
"""
Handles both GET and POST requests for the registration form.
- On GET, it displays an empty form.
- On POST, it validates the form data. If validation fails, it
re-renders the form with error messages. If successful, it
shows a success message and redirects.
"""
form = RegistrationForm()
if form.validate_on_submit():
# This block only runs if all form validators pass
# In a real application, you would save the user data to a database here.
# For this example, we'll just print it to the console.
print(f"User Registered: Username={form.username.data}, Email={form.email.data}")
# Show a success message
flash('Registration successful!', 'success')
# Redirect to the same page to show the success message and clear the form
return redirect(url_for('register'))
# Render the form template with the form object
return render_template_string(HTML_TEMPLATE, form=form)
# --- Run the App ---
if __name__ == '__main__':
# Setting debug=True automatically reloads the server on code changes
# This should be set to False in a production environment
app.run(debug=True, host='0.0.0.0', port=5000)
```
← Back to Projects