learning from 100 Days of Code: The Complete Python Pro Bootcamp for 2022
Flask - WTF Documentation
Flask - Bootstrap Documentation
Helpful Tutorial
Handling Forms in Flask with Flask-WTF
Python Flask Tutorial
Flask - WTForms
01. Install & set Form Template
Need to set secret key to trigger CSRF token
- stackoverflow - Where do I get a SECRET_KEY for Flask?
- stackoverflow - demystify Flask app.secret_key
# ------- Install -------#
$ pip install -U Flask-WTF
# ------- set Form Template-------#
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, length
class LoginForm(FlaskForm):
email = StringField(label="Email", validators=[DataRequired(), Email()])
password = PasswordField(label="Password", validators=[DataRequired(), length(min=8)])
submit = SubmitField(label="Log In")
02. Use in the front end
# ------- use in main.py -------#
@app.route("/login", methods=["GET", "POST"])
def login():
login_form = LoginForm()
# triggered only in POST request to check whether success or not
if login_form.validate_on_submit():
print(login_form.email.data)
print(login_form.password.data)
return render_template('login.html', form=login_form)
# ------- use in login.html -------#
<div class="container">
<h1>Login</h1>
<!-- novalidate: cancel auto pop-up from browser -->
<form method="POST" action="{{ url_for('login') }}" novalidate>
{{ form.csrf_token }}
<p>
{{ form.email.label }} <br> {{ form.email(size=30) }}
<!-- catch error and make feedback to user -->
{% for err in form.email.errors%}
<span style="color: red;">{{ err }}</span>
{% endfor %}
</p>
<p>
{{ form.password.label }} <br> {{ form.password(size=30) }}
<!-- catch error and make feedback to user -->
{% for err in form.password.errors%}
<span style="color: red;">{{ err }}</span>
{% endfor %}
</p>
{{ form.submit }}
</form>
</div>
Template Inheritance & Super Blocks
Template - base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
Insert Example - index.html
<!-- insert whole template -->
{% extends "base.html" %}
<!-- set block - title -->
{% block title %}
Secrets
{% endblock %}
<!-- set block - content -->
{% block content %}
<div class="jumbotron gray-300">
<div class="container">
<h1>Welcome</h1>
<p>Are you ready to discover my secret?</p>
<a class="btn btn-outline-dark btn-lg" role="button" href="{{ url_for('login') }}">Login</a>
</div>
</div>
{% endblock %}
Flask - Bootstrap
Flask - Bootstrap with Flask - WTForms
Total things you need to set
from flask import Flask
from flask_bootstrap import Bootstrap
app = Flask(__name__)
app.secret_key = os.getenv("secret_key")
Bootstrap(app)
Shorten whole page of login.html
{% extends 'bootstrap/base.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}
Login
{% endblock %}
{% block content %}
<div class="container">
<h1>Login</h1>
<!-- novalidate: cancel auto pop-up from browser -->
{{ wtf.quick_form(form, novalidate=True) }}
</div>
{% endblock %}
*省略部分語法,詳見GitHub