https://github.com/bendog/shecodes_flask_demo
Demo on how to make a really simple to follow flask website that focuses on learning over "doing it right"
https://github.com/bendog/shecodes_flask_demo
Last synced: 3 months ago
JSON representation
Demo on how to make a really simple to follow flask website that focuses on learning over "doing it right"
- Host: GitHub
- URL: https://github.com/bendog/shecodes_flask_demo
- Owner: bendog
- Created: 2020-03-26T11:35:59.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2022-09-16T18:25:14.000Z (almost 4 years ago)
- Last Synced: 2025-08-18T18:02:45.714Z (10 months ago)
- Language: HTML
- Size: 42 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Shecodes Flask Demo
Simplified demo of Flask
- [install dependences](#install-dependences)
- [shell / pipenv commands](#shell--pipenv-commands)
- [install](#install)
- [run](#run)
- [setup database](#setup-database)
- [make migrations](#make-migrations)
- [apply migrations](#apply-migrations)
- [notable changes](#notable-changes)
- [process of creating app.py](#process-of-creating-apppy)
- [**stage one:** show something](#stage-one-show-something)
- [**stage two:** show something pretty](#stage-two-show-something-pretty)
- [**stage three:** show more things](#stage-three-show-more-things)
- [**stage four:** create the database](#stage-four-create-the-database)
- [add packages with pipenv](#add-packages-with-pipenv)
- [setting up our flask database](#setting-up-our-flask-database)
- [defining our database model](#defining-our-database-model)
- [reading from the database model](#reading-from-the-database-model)
- [initialise, migrate and upgrade the database](#initialise-migrate-and-upgrade-the-database)
- [**stage five:** adding data to the database.](#stage-five--adding-data-to-the-database)
---
## install dependences
You'll need python 3.8
You'll need to install pipenv to create your virtual environment, to enable the .env file for the environment variable settings, and also to run the commands to run flask.
installing pipenv is as easy as
- `sudo pip3 install pipenv` (on mac)
- `pip install pipenv` (on windows)
## shell / pipenv commands
### install
pipenv install
### run
pipenv run flask run
### setup database
pipenv run flask db init
### make migrations
pipenv run flask db migrate
### apply migrations
pipenv run flask db upgrade
## notable changes
1. use app.py as a name, as it avoids having to introduce the concept of environmental variables
1. avoid blueprints, as we don't need to introduce the concept of multi-app tenancy to beginners
1. using pipenv, as it will load a .env file and have the same commands on windows, mac and linux.
1. add a way to add data to the database via a website, this was more exciting than using a form somewhere else
1. decided to use just one python file, as it makes it easier to conceptualise what's going on
## process of creating app.py
### **stage one:** show something
install flask
$ pipenv --three
... creating
$ pipenv install flask
... installing
create the environment file
`.env`
```shell
FLASK_ENV=development
```
create the app
` app.py`
```python
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "hello world"
# start the server with the 'run()' method
if __name__ == '__main__':
app.run(debug=True)
```
run flask
$ pipenv run flask run
... running
### **stage two:** show something pretty
copy in templates directory and files
edit `app.py`
```python
from flask import Flask, render_templates
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
# start the server with the 'run()' method
if __name__ == '__main__':
app.run(debug=True)
```
### **stage three:** show more things
edit `app.py`
```python
from flask import Flask, render_templates
app = Flask(__name__)
@app.route('/')
def index():
# return to template
return render_template(
'index.html', # which template
# all the variables for context go here
projects=[
{'name': 'day 1', 'description': 'html/css'},
{'name': 'day 2', 'description': 'python!'},
{'name': 'day 3', 'description': 'flask'},
],
)
@app.route('/contact')
def contact():
return render_template('contact.html')
@app.route('/about')
def about():
return render_template('about.html')
# start the server with the 'run()' method
if __name__ == '__main__':
app.run(debug=True)
```
talk about how templates work:
- context values
- loops
- include
- extend
### **stage four:** create the database
there's a lot of bits that need to be added here, most of this can be copy paste, but it's good to walk through.
#### add packages with pipenv
$ pipenv install flask-sqlalchemy
... installing
$ pipenv install flask-migrate
... installing
next we edit `app.py`, i'm going to do this in stages starting from the top.
#### setting up our flask database
```python
import os
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
##########
# config
##########
BASEDIR = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASEDIR, 'app.sqlite')
SQLALCHEMY_TRACK_MODIFICATIONS = False
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
...
```
We have to add a lot of config to our project to get the database working.
- we need to import SQLAlchemy and Migrate
- we need to configure where the database will be found
- then we need to bind the database to our flask app
#### defining our database model
I've chosen to do this in the same file, rather than creating a models.py file, because, we're aiming for absolute beginners, multiple files is just difficult to make sure everyone is editing the same file.
```python
...
# after migrate
# our project table
class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), index=True, unique=True)
description = db.Column(db.Text())
# before app.route('/')
...
```
this is our table for our projects.
#### reading from the database model
this is pretty simple, we just make our
```python
...
@app.route('/')
def index():
# # get the data
all_projects= Project.query.all()
# return to template
return render_template(
'index.html', # which template
# all the variables for context go here
all_projects=all_projects
)
...
```
#### initialise, migrate and upgrade the database
$ pipenv run flask db init
Creating directory /Users/bendog/dev/shecodes_flask_demo/migrations ... done
Creating directory /Users/bendog/dev/shecodes_flask_demo/migrations/versions ... done
Generating /Users/bendog/dev/shecodes_flask_demo/migrations/script.py.mako ... done
Generating /Users/bendog/dev/shecodes_flask_demo/migrations/env.py ... done
Generating /Users/bendog/dev/shecodes_flask_demo/migrations/README ... done
Generating /Users/bendog/dev/shecodes_flask_demo/migrations/alembic.ini ... done
Please edit configuration/connection/logging settings in '/Users/bendog/dev/shecodes_flask_demo/migrations/alembic.ini' before proceeding.
$ pipenv run flask db migrate
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'project'
INFO [alembic.autogenerate.compare] Detected added index 'ix_project_name' on '['name']'
Generating /Users/bendog/dev/shecodes_flask_demo/migrations/versions/1994ef3acb05_.py ... done
$ pipenv run flask db upgrade
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 1994ef3acb05, empty message
$ pipenv run flask run
after running these commands, flask should be running again and happy, however there's no data in the database, so lets add a way to add data.
### **stage five:** adding data to the database.
create a new html template
`update.html`
```html
{% extends 'base.html' %}
{% block heading %}
Update Project
{% endblock %}
{% block content %}
Send Message
{% endblock %}
```
update `nav.html`
```html
```
now add a new route to `app.py`
```python
...
@app.route('/update', methods=['GET', 'POST'])
def update():
# get the data from the form
if request.form:
data = request.form
# get the name
name = data['name']
print('name:', name)
# get the description
description = data['description']
print('description:', description)
# put the data in the database
new_project = Project(name=name, description=description)
db.session.add(new_project)
db.session.commit()
# redirect to home
return redirect(url_for("index"), code=303)
return render_template('update.html')
...
```
now our students can use a form to add new content to their index page, they get to see the joy of taking in data and seeing it change their page before their eyes!