Lecture 8.1 (March 8)
- Working on A2 and P3
- Q3 is after spring break
Resources
Loose Ends
- Make log-in buttons be buttons
- Drop excess cookie nonsense
- Make user available in all templates
- The
session
is directly available in Flask - There's also a 'Flask globals' object
flask.g
where you can stash stuff
- The
Modularity in Python
So far, we have written all code in one big file.
Python lets you split code into separate files, called modules.
We import code from other modules.
By default, our current directory is searched, along with other Python code.
We're going to split our application into several modules:
init
- This module contains the
app
object, along with other similar globals. views
- This module contains our
@app.route
URL handlers. It imports frominit
:from init import app
- myapp
- A main module that pulls everything together:
1. Import
init
2. Importviews
And, of course, manage.py
.
We can create other modules too, however we want to organize our code. Just a couple of rules:
- The myapp module needs to import every module that defines URL handlers, to make sure that they all get defined.
- To make
manage.py
work, it needs to also expose theapp
object
PyCharm will complain about unused imports; this is fine.
Note
If you read the Flask documentation on large applications, they suggest a somewhat different layout. Their layout breaks a common Python rule (with decent reason), but also requires more advanced understanding of the Python module system to understand, and does funny things to file paths.
Databases
We're now going to start using databases.
To do this, we are going to use SQLAlchemy and its Flask bridge. This allows us to write Python code to do basic (and many advanced) database operations.
Setting Up
First, we need to install it:
pip install flask-sqlalchemy
Then, we need to initialize SQLAlchemy in init.py
:
from flask_sqlalchemy import SQLAlchemy # … other init code db = SQLAlchemy(app)
Defining Data
We now can define the kinds of data we want to store. We will create a module, models
, that contains our database models.
Note
If you've heard of model-view-controller (MVC) architecture, this is it! The data is our model, the URL handlers are views, and effectively Flask is our controller.
In order to set up our data, we need to specify the different kinds of data we need to track, such as animals.
We define each kind of data as a Python class. It will then be used to create a database table.
class Animal(db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(50)) location = db.Column(db.String(50))
This defines a data type Animal
with three fields: an id (our objects should generally always have one of these), a name, and an animal.
There are a few rules:
- Always have an
id
column that is a primary key, to identify your objects. - No lists - just numbers, strings, etc.
We'll see in a bit how to link data types together.
Querying Data
Now we will update the Flask app to query data from us:
- Import
models
- Get animals by calling
Animal.query.all()
- Animals now have IDs, not just numbers — fix
index.html
- Get an animal with
Animal.query.get(…)
- Search animals with
Animal.query.filter_by(name=name).first()
Adding Data
We can add:
-
Create an object
animal = Animal() animal.name = name animal.location = home
-
Add it:
db.session.add(animal)
- Commit:
db.session.commit()
- Now
animal.id
has the animal ID
We can modify data too — just modify the object you got, then commit.
User Authentication
Work through how to create users and use bcrypt
.