python logo

Flask web forms

Python hosting: Host, run, and code Python in the cloud!
Flask wtforms Flask web form

In this tutorial you will learn how to do form validation with Flask. Forms play an important role in all web applications.

We use WTForms, a module for validation of forms. We will start with a simple form containing one field asking for a name.

Related course:
Python Flask: Make Web Apps with Python

from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField

# App config.
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'

class ReusableForm(Form):
name = TextField('Name:', validators=[validators.required()])

@app.route("/", methods=['GET', 'POST'])
def hello():
form = ReusableForm(request.form)

print form.errors
if request.method == 'POST':
name=request.form['name']
print name

if form.validate():
# Save the comment here.
flash('Hello ' + name)
else:
flash('All the form fields are required. ')

return render_template('hello.html', form=form)

if __name__ == "__main__":
app.run()

We then line_number:false create the template hello.html in the /templates/ directory:



<title>Reusable Form Demo</title>

{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{ { message[1] }}</li>
{% endfor %}</ul>
{% endif %}
{% endwith %}
<form action="" method="post">
&#123; &#123; form.csrf &#125;&#125;
<div class="input text">
{ { form.name.label }} { { form.name }}</div>
<div class="input submit">
<input type="submit" value="Submit"></div>
</form>

Start the application and open it in your webbrowser at http://127.0.0.1:5000.

python miniapp.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader

If you will submit an empty form, you will get an error. But if you enter your name, it will greet you. Form validation is handled by the wtforms module, but because we gave the argument

name = TextField('Name:', validators=[validators.required()])

the field cannot be empty. Other parameters can be given here.

python wtforms Python wtforms, text field validation. The app returns the name if entered

Related course:
Python Flask: Make Web Apps with Python

css with Flask

We use bootstrap to style the form.Bootstrap is a popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web. It makes front-end web development faster and easier. The output will be:

Flask wtforms Flask wtforms

You can get the bootstrap files from http://getbootstrap.com/getting-started/#download and extract them in a new directory /static/. The code remains almost the same, but the template is changed. Code:

from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField

# App config.
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'

class ReusableForm(Form):
name = TextField('Name:', validators=[validators.required()])

@app.route("/", methods=['GET', 'POST'])
def hello():
form = ReusableForm(request.form)

print form.errors
if request.method == 'POST':
name=request.form['name']
print name

if form.validate():
# Save the comment here.
flash('Hello ' + name)
else:
flash('Error: All the form fields are required. ')

return render_template('hello.html', form=form)

if __name__ == "__main__":
app.run()

We added bootstrap to the template hello.html:



<title>Reusable Form Demo</title>
<link rel="stylesheet" media="screen" href="static/bootstrap.min.css">
<link rel="stylesheet" href="static/bootstrap-theme.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<div class="container">
<h2>Flask Web Form</h2>
<form action="" method="post" role="form">
{ { form.csrf }}
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="What's your name?"></div>
<button type="submit" class="btn btn-success">Submit</button>
</form>{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}

{% for message in messages %}
{% if "Error" not in message[1]: %}
<div class="alert alert-info">
<strong>Success! </strong> { { message[1] }}</div>
{% endif %}

{% if "Error" in message[1]: %}
<div class="alert alert-warning">
{ { message[1] }}</div>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}

</div>

Related course:
Python Flask: Make Web Apps with Python

Flask registration form

We use the same principle to create a registration form asking for name, email and password. We update the Form class:

class ReusableForm(Form):
name = TextField('Name:', validators=[validators.required()])
email = TextField('Email:', validators=[validators.required(), validators.Length(min=6, max=35)])
password = TextField('Password:', validators=[validators.required(), validators.Length(min=3, max=35)])

def reset(self):
blankData = MultiDict([ ('csrf', self.reset_csrf() ) ])
self.process(blankData)

And we can get the variables passed using:

name=request.form['name']
password=request.form['password']
email=request.form['email']

Full code:

from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField

# App config.
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'

class ReusableForm(Form):
name = TextField('Name:', validators=[validators.required()])
email = TextField('Email:', validators=[validators.required(), validators.Length(min=6, max=35)])
password = TextField('Password:', validators=[validators.required(), validators.Length(min=3, max=35)])

@app.route("/", methods=['GET', 'POST'])
def hello():
form = ReusableForm(request.form)

print form.errors
if request.method == 'POST':
name=request.form['name']
password=request.form['password']
email=request.form['email']
print name, " ", email, " ", password

if form.validate():
# Save the comment here.
flash('Thanks for registration ' + name)
else:
flash('Error: All the form fields are required. ')

return render_template('hello.html', form=form)

if __name__ == "__main__":
app.run()

Update the template hello.html with this code:



<title>Reusable Form Demo</title>
<link rel="stylesheet" media="screen" href="static/bootstrap.min.css">
<link rel="stylesheet" href="static/bootstrap-theme.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<div class="container">
<h2>Flask Web Form</h2>
<form action="" method="post" role="form">
{ { form.csrf }}
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="What's your name?">

<label for="email">Email:</label>
<input type="text" class="form-control" id="email" name="email" placeholder="Your email will be used to contact you.">

<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Enter a password.">

</div>
<button type="submit" class="btn btn-success">Sign Up</button>
</form>{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}

{% for message in messages %}
{% if "Error" not in message[1]: %}
<div class="alert alert-info">
<strong>Success! </strong> { { message[1] }}</div>
{% endif %}

{% if "Error" in message[1]: %}
<div class="alert alert-warning">
{ { message[1] }}</div>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}

</div>


Output:

flask form bootstrap flask form bootstrap

Download Flask Examples

WTForms can validate email, password, numbers and many more. For a list of validators see: http://wtforms.readthedocs.org/latest/validators.html






Leave a Reply:




Duckpearl Sun, 19 Jul 2015

Could you explain a bit more about the following line of code?

def reset(self):
blankData = MultiDict([ ('csrf', self.reset_csrf() ) ])
self.process(blankData)

I can't see where it is used and I have never come across it in wtforms comments before.
Thanks

Frank Sun, 19 Jul 2015

Hi, thanks for the comment! This method is not used now, you can remove it. For CSRF protection see: http://flask.pocoo.org/snippets/3/

Connor Mon, 07 Sep 2015

In the first code example, where are you getting the request object from? Also, what are you doing when you are passing "methods=['GET', 'POST']" to app.route? Im a newbie to flask so please, explain it like im 5. :D thanks for the awesome tutorials!

Frank Mon, 07 Sep 2015

The request object is imported from flask on top.

Your computer communicates with a special computer called a server. This server sends you data such as this website. Both computers need to 'speak' a language to communicate, this language is called the HTTP protocol. The language is very simple, there are only a few words such as GET and POST.

A client (webbrowser) can send the "GET" word to the server, it will return the file you request. To give data to the server, you use the "POST" command.
When you opened this page, your web browser did the GET command. When you posted this comment, your browser did a POST command.

Flask is server side software. Python needs a way to connect the incoming HTTP commands (URLs) to functions, in this case "/", but may as well be "/connor". This process is called routing.

In the first example we define a route @app.route("/"), and map it to a function for both GET and POST commands. If a GET is send, the function returns a screen with the text input. If a POST is send, another output is shown.

Connor Tue, 08 Sep 2015

Thanks!

Alen Sat, 06 Mar 2021

I have a problem that I can't display a value to a textbox. I am new in flask and I tried to learn it by creating a Inventory web application. And now I was stuck in a point.The problem is that I need to display the balance quantity of an item to the text box or as a message in to the html page when the user entered quantity, greater than the balance quantity in that location. I fetch it from the database and can't display it into the textbox. Please help me. Thanks in advance.

Frank Sat, 06 Mar 2021

There are two methods to display new data on a webpage. After you get the data from the database, you return a new Flask view. This makes the webpage reload and you can show your data. An alternative to this is not reloading but using ajax and doing an ajax request to an API backend. You always use javascript for this, then using javascript get the data from the API and update the webpage. These days it's common to do that in VueJS but JQuery was common in the past.