Flask is a simple web framework written in Python.
In this article, we’ll look at how to develop simple Python web apps with Flask.
Form Validation with WTForms
We can add form validation into our Flask app with the WTForms library.
To install the library, we run:
pip install wtforms
Then we can use it by writing:
from flask import Flask, request
from wtforms import Form, BooleanField, StringField, PasswordField, validators
app = Flask(__name__)
class RegistrationForm(Form):
username = StringField('Username', [validators.Length(min=4, max=25)])
email = StringField('Email Address', [validators.Length(min=6, max=35)])
password = PasswordField('New Password', [
validators.DataRequired(),
validators.EqualTo('confirm', message='Passwords must match')
])
confirm = PasswordField('Repeat Password')
accept_tos = BooleanField('I accept the TOS', [validators.DataRequired()])
@app.route('/register', methods=['POST'])
def register():
form = RegistrationForm(request.form)
if request.method == 'POST':
if form.validate():
return 'thanks for registering'
else:
return 'registration failed'
We create the RegistrationForm
class that extends the Form
class from wtforms
.
We add the fields in there with the built in constructors.
StringField
creates a string field.
The first argument is the name.
The 2nd argument has the validation rules.
validators.length
checks the length.
PasswordField
creates a password field.
BooleanField
creates a boolean field.
validators.DataRequired()
lets us make a field required.
We can show fields and registration messages in our template by using a macro.
For example, we can write:
app.py
from flask import Flask, request, render_template
from wtforms import Form, BooleanField, StringField, PasswordField, validators
app = Flask(__name__)
class RegistrationForm(Form):
username = StringField('Username', [validators.Length(min=4, max=25)])
email = StringField('Email Address', [validators.Length(min=6, max=35)])
password = PasswordField('New Password', [
validators.DataRequired(),
validators.EqualTo('confirm', message='Passwords must match')
])
confirm = PasswordField('Repeat Password')
accept_tos = BooleanField('I accept the TOS', [validators.DataRequired()])
@app.route('/register', methods=['GET','POST'])
def register():
form = RegistrationForm(request.form)
if request.method == 'POST' and form.validate():
return 'thanks for registering'
return render_template('register.html', form=form)
templates/_formhelpers.html
{% macro render_field(field) %}
<dt>{{ field.label }}
<dd>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endmacro %}
templates/register.html
{% from "_formhelpers.html" import render_field %}
<form method=post>
<dl>
{{ render_field(form.username) }}
{{ render_field(form.email) }}
{{ render_field(form.password) }}
{{ render_field(form.confirm) }}
{{ render_field(form.accept_tos) }}
</dl>
<p><input type=submit value=Register>
</form>
We create the render_field
macro that we use with the register.html
template.
The field
function renders the field.
field.errors
renders the errors.
In the register.html
file, we call render_field
to render the fields with the errors with the render_field
macro.
Template Inheritance
We can inherit from a base template so we can have shared items in there.
For example, we can write:
app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def register():
return render_template('index.html')
templates/layout.html
<!doctype html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2010 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
</html>
templates/index.html
{% extends "layout.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my awesome homepage.
{% endblock %}
static/style.css
body {
font-size: 20px;
}
In layout.html
, we add the blocks with the block
keyword.
Then we override them with our own content with the index.html
template.
Conclusion
We can add form validation and base templates with Flask.