- Build One to many crud app
- Add flask login
- refactor with blueprints
In terminal:
take flask-fishes
mkvirtualenv flask-fishes
pip install flask flask_sqlalchemy wtforms psycopg2 flask_bcrypt flask_migrate flask_modus
touch {app,manage,forms}.py
take templates
touch base.html
mkdir fishes
mkdir users
touch fishes/{index,new,show,edit}.html
touch users/{index,new,show,edit}.html
pip freeze > requirements.txt
git init
echo __pycache__ > .gitignore
echo *.pyc >> .gitignore
createdb flask_fishes
App.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://localhost/flask-fishes'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.Text(), nullable=False, unique=True)
passwod = db.Column(db.Text(), nullable=False)
fishes = db.relationship('Fish', backref='user', lazy='dynamic')
def __init__(self, username, password):
self.username = username
self.password = bcrypt.generate_password_hash(password).decode('utf-8')
class Fish(db.Model):
__tablename__ = 'fishes'
id = db.Column(db.Integer, primary_key = True)
type = db.Column(db.Text()), nullable = False)
weight = db.Column(db.Float, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
def __init__(self, type, weight, user_id):
self.type = type
self.weight = weight
self.user_id = user_id
@app.route('/users')
def index():
return render_template('users/index.html', form= form)
@app.route('/users/new')
def new():
form = UserForm()
return render_template('users/new.html', form = form)
@app.route('/')
def create():
form = UserForm()
@app.route('/login', methods = ['GET', 'POST'])
def login():
error = None
form = UserForm()
if form.validate_on_submit():
found_user = User.query.filter_by(username=form.username.data)
if found_user:
is_authenticated = bcrypt.check_password_hash(found_user.password, form.password.data)
if is_authenticated:
flash ('User Logged in!')
return redirect(url_for('index'))
else:
error = "Invalid Username/Password
else:
@app.route('/')
def ():
if __name__ = '__main__':
app.run(debug=True, port=3000)
in manage.py:
from app import app,db
from flask_script import Manager
from flask)migrate import Migrate, MigrateCommand
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ = '__main__':
manager.run()
in terminal, run:
createdb flask-fishes
python manage.py db init
python manage.py db migrate
in forms.py:
from flask_wtf import Form
from wtforms import StringField, PasswordField, FloatField
from wtforms.validators import DataREquired, Length
class UserForm(Form):
username = StringField('username', validators = [ DataRequired()])
password = PasswordField('password, validators = [DataRequired(), Length(6) ])
class FishForm(Form):
type = StringField('type', validators = [DataRequired()] )
weight = FloatField('weight', validators = [DataRequired()] )
- Create users
- List out users
- Make a page to log in a user
In terms of routes,
- GET
- users/new
- /login
- /users
- POST
- /users
- /login
- Sessions
What we've done with Elie following the break
1 Start to use validation, bcrypt for forms 2 Include CsrfProtect for all form templates 3 LoginManager for state