Flask Tutorial templates, webforms, database and user logins - Part 1
In this tutorial, you are going to learn how to set up a Flask project.
By the end of this chapter part 1 you are going to have a simple Flask web application login system
below is a list.
1. Templates
how to work with templates
2. Web Forms
how to work with web forms
To handle the web forms in this application we will use the Flask-WTF extension
install Flask-WTF in your virtual environment:
(venv) $ pip install flask-wtf
3. Database
how to work with databases.
To install Flask-SQLAlchemy in your virtual environment, make sure you have activated it first, and then run:
(venv) $ pip install flask-sqlalchemy
4. User Logins
how to create a user login subsystem
install Flask-Login in your virtual environment:
(venv) $ pip install flask-login
#app.py from flask import Flask, render_template, flash, redirect, url_for from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, BooleanField, SubmitField from wtforms.validators import DataRequired from flask_sqlalchemy import SQLAlchemy from datetime import datetime from werkzeug.security import generate_password_hash, check_password_hash from flask_login import LoginManager, UserMixin, current_user, login_user, logout_user, login_required app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db' app.config['SECRET_KEY'] = 'cairocoders-ednalan' login = LoginManager(app) login.login_view = 'login' db = SQLAlchemy(app) class LoginForm(FlaskForm): username = StringField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()]) remember_me = BooleanField('Remember Me') submit = SubmitField('Sign In') class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password_hash = db.Column(db.String(128)) def __repr__(self): return ''.format(self.username) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) class Post(db.Model): id = db.Column(db.Integer, primary_key=True) body = db.Column(db.String(140)) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __repr__(self): return ' '.format(self.body) @login.user_loader def load_user(id): return User.query.get(int(id)) @app.route('/') @app.route('/index') @login_required def index(): user_post = {'username': 'cairocoders'} hash = generate_password_hash('test1') check_hash = check_password_hash(hash, 'test1') posts = [ { 'author': {'username': 'tutorial1'}, 'body': 'Beautiful day in Olongapo City!' }, { 'author': {'username': 'turorial10'}, 'body': 'Flask is a lightweight WSGI web application framework.!' } ] return render_template('index.html', title='Home', user_post=user_post, posts=posts, hash=hash, check_hash=check_hash) @app.route('/login', methods=['GET', 'POST']) def login(): if current_user.is_authenticated: return redirect(url_for('index')) form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() if user is None or not user.check_password(form.password.data): flash('Invalid username or password') return redirect(url_for('login')) login_user(user, remember=form.remember_me.data) return redirect(url_for('index')) return render_template('login.html', title='Sign In', form=form) @app.route('/logout') def logout(): logout_user() return redirect(url_for('index')) if __name__ == '__main__': app.run(debug=True)
//templates/index.html {% extends "base.html" %} {% block content %} <p>hash, {{ hash }}!</p> <p>Check hash, {{ check_hash }}</p> <h1>Hi, {{ current_user.username }}!</h1> {% for post in posts %} <div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div> {% endfor %} {% endblock %}
//templates/base.html <html> <head> {% if title %} <title>{{ title }} - blog</title> {% else %} <title>Welcome to blog</title> {% endif %} </head> <body> <div> Blog: <a href="{{ url_for('index') }}">Home</a> {% if current_user.is_anonymous %} <a href="{{ url_for('login') }}">Login</a> {% else %} <a href="{{ url_for('logout') }}">Logout</a> {% endif %} </div> <hr> <p>Flask Tutorial templates, webforms, database and user logins - Part 1</p> {% with messages = get_flashed_messages() %} {% if messages %} <ul> {% for message in messages %} <li>{{ message }}</li> {% endfor %} </ul> {% endif %} {% endwith %} {% block content %}{% endblock %} </body> </html>
//templates/login.html {% extends "base.html" %} {% block content %} <h1>Sign In</h1> <form action="" method="post" novalidate> {{ form.hidden_tag() }} <p> {{ form.username.label }}<br> {{ form.username(size=32) }}<br> {% for error in form.username.errors %} <span style="color: red;">[{{ error }}]</span> {% endfor %} </p> <p> {{ form.password.label }}<br> {{ form.password(size=32) }}<br> {% for error in form.password.errors %} <span style="color: red;">[{{ error }}]</span> {% endfor %} </p> <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p> <p>{{ form.submit() }}</p> </form> {% endblock %}