Python Part 8: Building a Web Application
Last Updated by Code Sport. Filed under classes, courses, pythonPython and Flask: Building a Complex Web Application Pro Tip: Install and…
Install:
pip install Flask-SQLAlchemy
Uninstall:
pip uninstall Flask-SQLAlchemy
Install Flask-SQLAlchemy to form an abstraction layer between a database (e.g., MySQL, PostgreSQL, SQLite) and Python. SQLAlchemy allows querying a database with Python code as opposed to SQL. Read the SQLAlquemy’s Object Relational Mapping tutorial for usage and syntax details.
$ pip install flask-sqlalchemy
This is the directory structure for a Flask python package as well as how to import each module:
./ └── Appname/ ├── runserver.py #import appname.runserver └── appname/ #folder contains '__init__.py' so this is the package name ├── __init__.py #import appname ├── static/ │ ├── css/ │ ├── img/ │ └── js/ ├── templates/ │ ├── index.htm │ ├── login.htm │ ├── registration │ └── file-a.htm │ ├── views.py #import appname.views ├── file_1.py #import appname.file_1 ├── file_n.py #import appname.file_n ├── models.py #import appname.model └── README.md
runserver.py
facilitates package creation with Flask by allowing us to use multiple modules with the Flask framework.
from appname import app #http://flask.pocoo.org/docs/0.10/patterns/packages/#simple-packages app.run(debug=True)
Tells Python to treat our folder (application) as a package. __init__.py contains application-wide imports and configurations. It also imports View functions (the ones with a route() decorator on top).
from flask import Flask app = Flask(__name__) #create a Flask object called 'app'. The __name__ variable is the package name (http://flask.pocoo.org/docs/0.10/api/#application-object) app.secret_key = 'development key' app.config["MAIL_SERVER"] = "smtp.gmail.com" app.config["MAIL_PORT"] = 465 app.config["MAIL_USE_SSL"] = True app.config["MAIL_USERNAME"] = 'contact@example.com' app.config["MAIL_PASSWORD"] = 'password from views import mail mail.init_app(app) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@localhost/db_name' from models import db db.init_app(app) import appname.views #always at the bottom of your file. See "circular imports"
from appname import app # which is in __init__.py See "circular imports" from flask import render_template, request, flash, session, url_for, redirect from forms import ContactForm, SignupForm, SigninForm from flask.ext.mail import Message, Mail from models import db, User mail = Mail() @app.route('/') def home(): return render_template('home.html') @app.route('/about') def about(): return render_template('about.html') @app.route('/contact', methods=['GET', 'POST']) def contact(): form = ContactForm() if request.method == 'POST': if form.validate() == False: flash('All fields are required.') return render_template('contact.html', form=form) else: msg = Message(form.subject.data, sender='contact@example.com', recipients=['your_email@example.com']) msg.body = """ From: %s <%s> %s """ % (form.name.data, form.email.data, form.message.data) mail.send(msg) return render_template('contact.html', success=True) elif request.method == 'GET': return render_template('contact.html', form=form) @app.route('/signup', methods=['GET', 'POST']) def signup(): form = SignupForm() if 'email' in session: return redirect(url_for('profile')) if request.method == 'POST': if form.validate() == False: return render_template('signup.html', form=form) else: newuser = User(form.firstname.data, form.lastname.data, form.email.data, form.password.data) db.session.add(newuser) db.session.commit() session['email'] = newuser.email return redirect(url_for('profile')) elif request.method == 'GET': return render_template('signup.html', form=form) @app.route('/profile') def profile(): if 'email' not in session: return redirect(url_for('signin')) user = User.query.filter_by(email = session['email']).first() if user is None: return redirect(url_for('signin')) else: return render_template('profile.html') @app.route('/signin', methods=['GET', 'POST']) def signin(): form = SigninForm() if 'email' in session: return redirect(url_for('profile')) if request.method == 'POST': if form.validate() == False: return render_template('signin.html', form=form) else: session['email'] = form.email.data return redirect(url_for('profile')) elif request.method == 'GET': return render_template('signin.html', form=form) @app.route('/signout') def signout(): if 'email' not in session: return redirect(url_for('signin')) session.pop('email', None) return redirect(url_for('home'))
from flask.ext.sqlalchemy import SQLAlchemy from werkzeug import generate_password_hash, check_password_hash db = SQLAlchemy() class User(db.Model): __tablename__ = 'users' uid = db.Column(db.Integer, primary_key = True) firstname = db.Column(db.String(100)) lastname = db.Column(db.String(100)) email = db.Column(db.String(120), unique=True) pwdhash = db.Column(db.String(54)) def __init__(self, firstname, lastname, email, password): self.firstname = firstname.title() self.lastname = lastname.title() self.email = email.lower() self.set_password(password) def set_password(self, password): self.pwdhash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.pwdhash, password)