Matthew McElwee Matthew McElwee - 1 year ago 223
Python Question

Python Flask Login login_required redirecting

I am working on a Flask app and using Flask-Login for authentication. Everything is set up and running. However when the user logins in and attempts to visit a page that requires login, they are redirected to the login page.

When watching the console, I get a 200 for the GET login page, a 200 for the POST on the login, a 302 from the login page to the home page, and then another 302 from the homepage back to login.

See code below.

from flask import (Flask, render_template, g, flash, redirect, url_for,
from flask_bcrypt import check_password_hash
from flask_login import (LoginManager, UserMixin, login_required, login_user,
logout_user, current_user)

import models
import forms

application = Flask(__name__)
application.secret_key = "xxx-xxx-xxx-xxx"
login_manager = LoginManager()
login_manager.login_view = "login"

def before_request():
g.db = models.DATABASE
g.user = current_user

def after_request(response):
return response

def load_user(email):
return == email).get()
except models.DoesNotExist:
return None

@application.route("/register", methods=['GET', 'POST'])
def register():
form = forms.RegisterForm()
if form.validate_on_submit():
flash("Yay! You registered!", "success")
email =,
password =
return redirect(url_for('home'))
return render_template('register.html',form=form)

@application.route("/login", methods=['GET', 'POST'])
def login():
form = forms.LoginForm()
if form.validate_on_submit():
next = request.args.get('next')
user = models.User.get( ==
except models.DoesNotExist:
flash("Your email or password doesn't match!", "error")
if check_password_hash(user.password,
login_user(user, remember=True)
flash("Welcome back!", "success")
return redirect(next or url_for("home"))
flash("Your email or password doesn't match!", "error")
return render_template("login.html", form=form)

def logout():
flash("You've been logged out!", "success")
return redirect(url_for("home"))

def home():
return render_template("home.html")

if __name__ == "__main__":

Here is the model:

import datetime

from flask_login import UserMixin
from flask_bcrypt import generate_password_hash, check_password_hash
from peewee import *

DATABASE = MySQLDatabase("fakedatabasename", host="fakehostname", user="fakeusername", password="fakepassword")

class BaseModel(Model):
class Meta:
database = DATABASE

class Preachers(BaseModel):
preacher_id = PrimaryKeyField()
preacher_first_name = CharField(max_length=27)
preacher_last_name = CharField(max_length=27)
preacher_email = CharField()

class Sermons(BaseModel):
sermon_id = PrimaryKeyField()
sermon_title = CharField(max_length=27)
sermon_description = CharField(max_length=140)
sermon_date = DateTimeField(
sermon_preacher_id = IntegerField()
sermon_video_uri = CharField(max_length=255)

class User(UserMixin,BaseModel):
user_id = PrimaryKeyField()
email = CharField(index=True, unique=True)
password = CharField()
date_created = DateTimeField(

def create_user(cls, email, password):
email = email,
password = generate_password_hash(password)
except IntegrityError:
raise ValueError("User already exists")

def initialize():
DATABASE.create_tables([Preachers, Sermons, User], safe=True)

Answer Source

So it turns out that when working with Peewee and Flask-Login, you need to let Peewee supply its default primary key for the User model instead of using a custom one. Removing user_id = PrimaryKeyField(), dropping the table, and restarting fixed it.