In this Flask Tutorial we are going to learn about creating Flask Forms with Flask-WTF.
so Flask-WTF is simple integration of Flask and WTForms, including CSRF, file upload, and
reCAPTCHA. and this is our eight article on Flask Web Development.
Features :
- Integration with WTForms.
- Secure Form with CSRF token.
- Global CSRF protection.
- reCAPTCHA support.
- File upload that works with Flask-Uploads.
- Internationalization using Flask-Babel.
If you are interested in Web Development with Django Framework, than you can read the
complete articles in this link, Django Web Development Tutorials.
Installation
First of all you need to install Flask-WTF, you can easily install Flask-WTF using pip command.
1 |
pip install Flask-WTF |
First of all you need to create a new python file at name of forms.py, basically in this file we are going to create our form. also you can see that we have used validators for our input fields. a validator simply takes an input, verifies it fulfills some criterion, such as a maximum length for a string and returns. Or, if the validation fails, raises a ValidationError. this system is very simple and flexible, and allows you to chain any number of validators on fields.
1 2 3 4 5 6 7 8 9 10 |
from flask_wtf import FlaskForm from wtforms import StringField, PasswordField from wtforms.validators import InputRequired class LoginForm(FlaskForm): username = StringField('Username', validators=[InputRequired()]) password = PasswordField('Password', validators=[InputRequired()]) |
OK now we need to add a new view function in our app.py file at name of Login, basically we are going to just create the object of our form in here and we render our form. also you can see we have validated our request for the view handler.
1 2 3 4 5 6 7 8 |
@app.route('/login' , methods = ['GET', 'POST']) def Login(): form = LoginForm() if form.validate_on_submit(): return 'Form Submitted Successfully' return render_template('login.html', form = form) |
This is our complete app.py file. also when you are working with the forms you need to configure the secret key at the top.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
from flask import Flask, render_template from forms import LoginForm #create the object of Flask app = Flask(__name__) app.config['SECRET_KEY'] = 'hardsecretkey' #creating our routes @app.route('/') def index(): return render_template('index.html') @app.route('/login' , methods = ['GET', 'POST']) def Login(): form = LoginForm() if form.validate_on_submit(): return 'Form Submitted Successfully' return render_template('login.html', form = form) #run flask app if __name__ == "__main__": app.run(debug=True) |
This is our base.html, we have already talked about creating templates in Flask, you can read this article Introduction to Flask Templates. you need to just create templates folder in your working directory.
templates/base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %}</title> <!-- CSS Bootstrap CDN Link --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="{{url_for('index')}}">CodeLoop</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="{{url_for('index')}}">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Logout</a> </li> </ul> <form class="form-inline my-2 my-lg-0"> <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> </div> </div> <a href="{{url_for('Login')}}"><button class="btn btn-success navbar-btn">Login</button> </a> <a href=""><button class="btn btn-success navbar-btn">Signup</button> </a> </nav> <!-- JS, Popper.js, and jQuery --> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script> {% block body %} {% endblock %} </body> </html> |
In our base.html file we have already added a button for login. and you can see that we have
linked our button to the Login view function that we have already created in our app.py file.
1 |
<a href="{{url_for('Login')}}"><button class="btn btn-success navbar-btn">Login</button> </a> |
Now this is our login.html file. we have just simply rendered our form fields in here. you can see that at the top we have added {{form.csrf_token}}, this hidden field is created automatically. Flask-WTF form is already protecting you from CSRF, you don’t have to worry about that. However, you have views that contain no forms, and they still need protection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{{form.csrf_token}} <p> {{form.username.label}} {{form.username(size=32)}} </p> <p> {{form.password.label}} {{form.password(size=32)}} </p> <p> <input type="submit" value="Login" class="btn btn-success"> </p> |
So this is the complete file for login.html.
templates/login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
{% extends 'base.html' %} {% block title %} Home {% endblock %} {% block body %} <div class="container"> <h1>Home Page - Welcome to codeloop.org</h1> <h3>Tutorial Number 8 </h3> <br> <br> <hr> <h1>Please Login</h1> <form action="" method="post" novalidate> {{form.csrf_token}} <p> {{form.username.label}} {{form.username(size=32)}} </p> <p> {{form.password.label}} {{form.password(size=32)}} </p> <p> <input type="submit" value="Login" class="btn btn-success"> </p> </form> </div> {% endblock %} |
And this is our index.html file.
templates/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{% extends 'base.html' %} {% block title %} Home {% endblock %} {% block body %} <div class="container"> <h1>Home Page - Welcome to codeloop.org</h1> <h3>Tutorial Number 8 </h3> <p> In this tutorial we are going to talk about Flask-WTF forms. </p> </div> {% endblock %} |
Now if you run the project and click on the login button, you will see your login form.
http://localhost:5000/login
Also you can watch my complete 4 hours training on Flask Web Development
Subscribe and Get Free Video Courses & Articles in your Email
Comments are closed.