More Flask: Databases & Forms

Umar Khan
5 min readApr 15, 2021

I said last post I would revisit Flask. Here I am, true to my word!

So the app I wanted to make was a task/project management app. I know, I know; theres no shortage of such apps out there. But for some reason they never seemed to quit fit my needs. Besides I wanted something much more…basically one giant app to organize my life, where I could keep contacts, documents, thoughts (“It’s called g-suite Umar!”). I got started working on this app and quickly realized it was a much larger project than I thought. But I got the task entry part working and I was so excited I couldnt wait to share it!

Last post, I showed you how routes and templates work in Flask. Today lets look at Databases and Forms. I will use SQL Alchemy, which is an Object Relational Mapper. It allows us to manage databases using classes & methods instead of tables and SQL, which is more intuitive in Python. It also scales better, and makes it easy to swap out databases later on if you want. The Flask-SQLAlchemy Quickstart is a good place to see how to start. First, run “pip install flask-sqlalchemy” and then look at the code below:

Lets break this down. First we import SQLAlchemy. Then we have to set the app’s config to point it to the right database, which we do by setting the “'SQLALCHEMY_DATABASE_URI’ value to ‘’sqlite:////tmp/test.db’. This is a standard way to specify the type and location in SQLAlchemy, in this case sqlite located in the tmp folder of our root folder. Finally, we need to instantiate our database interface by passing the app into SQLAlchemy.

In SQL Alchemy, the way we implement SQL tables is by creating class for each table. This class extends the Model class of SQLAlchemy. In side this new class, we will define the columns of our table as shown above: simply specify a column name and then specify it as a Column type and pass in value to specify the type of data the column will hold. So for my project, I want a table to hold all the tasks I will add. i will create a new module in my app folder and call it models.py, and in it I will create the class:

I imported the db object from the main app module and used it to subclass Model to create my Entry table. I specify four columns, specifying the type of data going into each. For the string type columns, I further specify the number of charachters each entry can have.

Now lets look at how to build forms in Flask. This is super easy with the Flask-WTF library. Go ahead and run “pip install flask-wtf”. Now to create our our form we will simply subclass the FlaskForm object from this library similar to how we set up our database table above. Create another module in your app folder called forms.py and enter the code below:

Notice how we mirrored the fields in our table, except the id column. This will be automatically populated by SQLAlchemy. We import the needed field types from wtforms and set each field to that type, passing in the label to be displayed as parameters. We also add a Submit called Save which will serve as our submission button.

In order to display this form in the browser, we will have to pass it into a template. Take a look at the template I set up:

This is a partial view of the template. The part we are concerned with is second like and the div of the class “col-md-4”. We could manually craft the html segments for each field, but we can use the convenient wtf.html template from the bootstrap library to quicky display the form. This is imported from that second line. To use bootstrap, first install it using pip install flask-bootstrap. Then in your init module just add the line bootstrap = Bootstrap(app). Now, in the div where we want to display the form we simply pass the form vairable into wtf.quick_form. This will display all the fields from the form in that div.

So we have our database table and our form. Now to tie these together so users can use the form to enter data into the table. This will be done in the routes module, in the view function. Lets see what this looks like:

First off, we modified decorater to specify the methods it can accept: we include POST because thats how forms send data entered by the user on their browser back to the server. Then we instantiate an EntryForm object from the class we created earlier and save it to the ‘form’ variable. Now lest skip to the last line for second, the return statement. Notice how we just pass in form variable to the ‘form’ paramter, and this will pass it to our template which if you remember is expected a variable named “form” which it will then render as a form.

Then we have the code that handles the actual submission of form data. The line “if form.validate_on_submit()” checks to see if the forms submit button has been clicked, and evaluates to true if it has. So when the user clicks submit, a POST request is sent to the route and the validate_on_submit value of the form element is set to True. This is how we know the form has been submit. Inside this conditional, we first use the “flash” method to flash a message to the user letting them know that the form has been submitted.

Then, we instantiate an Entry object, which remember is a SQLAlchemy object that serves as a container for a database entry. We simply set the attributes of this object that we defined in the class to the data entered into the releated form fields. Then we pass in this object to the db using ‘db.session.add(entry)’, and then save out changes to the db using the commit method.

Easy!! You now know how to set up forms using Flask. Go forth and code!

--

--

Umar Khan

Just an attorney who wandered into data science and never wanted to leave.