====== Webapps with Flask ====== ===== Starting point ===== ==== Frameworks ==== * Flask * [[https://pythonhosted.org/Flask-SQLAlchemy/index.html|Flask-SQLAlchemy]] * [[https://flask-restless.readthedocs.org/en/latest|Flask-Restless]] * Angular.js Base from: [[https://www.youtube.com/watch?v=2geC50roans#t=599]] ==== First overview ==== #!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask from flask.ext.sqlalchemy import SQLAlchemy from flask.ext.restless import APIManager app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///digin.db' db = SQLAlchemy(app) class Card(db.Model): id = db.Column(db.Integer, primary_key=True) front = db.Column(db.Text) rever = db.Column(db.Text) db.create_all() api_manager = APIManager(app, flask_sqlalchemy_db=db) api_manager.create_api(Card, methods=['GET', 'POST', 'DELETE', 'PUT']) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run() It allows to access to different urls: * [[http://127.0.0.1:5000/api/card]] * [[http://127.0.0.1:5000/api/card/1]] ===== Model ===== ==== Interact with model classes ==== Only importing the code file and using the class you will be interacting with the data base: from person_app import Person from person_app import db p = Person(name='Juan', age=33) Person.query.all() db.session.add(p) db.session.commit() ==== Relationships with SQLAlchemy ==== === One to one === class Person(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) addresses = db.relationship('Address', backref='person', lazy='dynamic') class Address(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(50)) person_id = db.Column(db.Integer, db.ForeignKey('person.id')) === One to many === class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) addresses = db.relationship('Address', backref=db.backref('person', lazy='joined'), lazy='dynamic') === Many to many === tags = db.Table('tags', db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')), db.Column('page_id', db.Integer, db.ForeignKey('page.id')) ) class Page(db.Model): id = db.Column(db.Integer, primary_key=True) tags = db.relationship('Tag', secondary=tags, backref=db.backref('pages', lazy='dynamic')) class Tag(db.Model): id = db.Column(db.Integer, primary_key=True) === Define fields === class Deck(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Text, nullable=False) date = db.Column(db.DateTime, default=datetime.now()) cards = db.relationship('Card', backref='deck', lazy='dynamic') class Card(db.Model): id = db.Column(db.Integer, primary_key=True) id_deck = db.Column(db.Integer, db.ForeignKey('deck.id'), nullable=False) front = db.Column(db.Text) rever = db.Column(db.Text) === Separate model in another file === The ''flaskext.sqlalchemy'' module does not have to be initialized with the app right away - you can do this instead: # apps.members.models from flaskext.sqlalchemy import SQLAlchemy db = SQLAlchemy() class Member(db.Model): # fields here pass And then in your application setup you can call init_app: # apps.application.py from flask import Flask from apps.members.models import db app = Flask(__name__) # later on db.init_app(app) Example: # apps.shared.models from flaskext.sqlalchemy import SQLAlchemy db = SQLAlchemy() # apps.members.models from apps.shared.models import db class Member(db.Model): # TODO: Implement this. pass # apps.reporting.members from flask import render_template from apps.members.models import Member def report_on_members(): # TODO: Actually use arguments members = Member.filter(1==1).all() return render_template("report.html", members=members) # apps.reporting.routes from flask import Blueprint from apps.reporting.members import report_on_members reporting = Blueprint("reporting", __name__) reporting.route("/member-report", methods=["GET","POST"])(report_on_members) # apps.application from flask import Flask from apps.shared import db from apps.reporting.routes import reporting app = Flask(__name__) db.init_app(app) app.register_blueprint(reporting) Another example: app = Flask(__name__, static_path='') app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///digin.db' db.init_app(app) with app.app_context(): db.create_all() ===== HTML and JavaScript ===== ==== Install JS libraries ==== $ sudo apt-get install nodejs $ sudo apt-get install npm $ sudo npm install -g bower $ sudo ln -s /usr/bin/nodejs /usr/bin/node Inside the static folder... $ bower install angular