This is the learning notes of the tutorials from Corey Schafer.
1. In the root direcotry we can create a python script called "forms.py" to define how our forms look like. To do a project it is better to make everything to have it's own place and looks clean. Just like "main.css" explaned before, we also define forms in a single file.
2. We always want to have registration or login forms in our web page to get information from user and post it to our server. Following is the modules that we need to define the forms.
from flask_wtf import FlaskForm
# import the main module, the form
from wtforms import StringField, PasswordField, SubmitField, BooleanField
# for different form types, we need to import different Field, do as you need
from wtforms.validators import DataRequired, Length, Email, EqualTo
# Sometimes we need to check if the users input is what we expected, for this we need the validators
3. And for different purpose, we can define different classes with a block of forms, which extends the class FlaskForm. Here a simple example for registration is given. Of course, we can also do Login forms, Application forms, etc..
class RegistrationForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)])
email = StringField('Email',
validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
confirm_password = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sign Up')
4. To use these forms, we always need to create a secret key, which can protect against cookies and cross-site request forgery attacks and so on. To achive this, we can insert the following line in out main routes file. On the right side, it is just some random charactors which can be generated by python built-in module "secrets".
app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245'
# You can open a terminal and use python to generate the random charactors
import secrets
secrets.token_hex(16) # 16 means the number of bytes
5. Now, we can import the classes that we defined to our routes file and use it this way, for example.
from forms import RegistrationForm
@app.route("/register", methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
flash(f'Account created for {form.username.data}!', 'success')
return redirect(url_for('home'))
return render_template('register.html', title='Register', form=form)
# flash returns us a message, which would be show in the correspondent place of the
# page(this show be defined in the layout file, given below).and tell us if the
# information in the forms are correct.
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
6. In the correspondent "register.html", we can define the page as below. At the end, an anchor example is also given. This can route us to another page.
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Join Today</legend>
<div class="form-group">
{{ form.username.label(class="form-control-label") }}
{% if form.username.errors %}
{{ form.username(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username(class="form-control form-control-lg") }}
{% endif %}
</div>
<!--Of course, we should insert more div tags, here is just an example-->
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
<div class="border-top pt-3">
<small class="text-muted">
Already Have An Account? <a class="ml-2" href="{{ url_for('login') }}">Sign In</a>
</small>
</div>
{% endblock content %}