Forms

Structured forms are how user input is sanitized and trusted. This webapp utilizes Flask_WTF which lets us integrate WTForms in Flask. WTForms is a simple data validation library to make sure users aren’t putting js scripts into their username box, among other nefarious things.

Field Objects

Forms are established in website/app/forms, and each form will get a new file.

In login_form.py there is a class,

class LoginForm(FlaskForm):
    username = StringField("DB Username", validators=[DataRequired()])
    password = PasswordField("DB Password", validators=[DataRequired()])
    submit = SubmitField("Login")

which extends the FlaskForm class. The attributes of the class are whatever fields you want that form to have.

Since this is a login form we need a username, password, and submit button.

  • Username: normal text field, so use the StringField.
  • Password: we want the characters hidden on screen so use PasswordField.
  • Submit button: SubmitField object validates/packages the form data into headers before resubmitting the request to the url of the page it is on.

All field objects are listed in great length on the FlaskWTF docs.

Validators

Validators verify that the input fits a set of criteria based off what validator object is used. The DataRequired object ensures the field is not empty on submit. More specifically, it checks that form.<field>.data exists.

This is important since in app/routes/auth_routes.py it does

if form.validate_on_submit():
    username = form.username.data
    password = form.password.data

which wouldn’t be possible if the login fields were left empty.

Validators should always be used!

Rendering in HTML

The form object is passed to the render_template function so it can be placed in the html file.

Use Jinja templating to place the passed form as html elements.

{{ form.username.label }}
{{ form.username }}
{{ form.password.label }}
{{ form.password }}
{{ form.submit }}

Every single form should (I hope…) follow this structure with little deviation.

Jinja