1

I am trying to create a basic blog post website. Everything was going fine until i tried to run the app and it showed me the error:-

"Exception: Missing user_loader or request_loader"

but I have already created the user_loader. so I tried to find solutions and in the process I found that flask db migrate is not creating any table. so I searched online and found a solution to add all my tables in evn.py file in migration folder. I thought that was the problem and I tried to run the app again and this appeared again:-

"Exception: Missing user_loader or request_loader"

This is my __init__py file

# blogpost/__init__.py
import os
import secrets
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager

app = Flask(__name__)
app.config['SECRET_KEY'] = secrets.token_hex(8)

# DATABASE CONFIGURATION #############
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)
Migrate(app, db)

# LOGIN CONFIGURATION #################
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'users.login'

# IMPORTING BLUEPRINTS #################################
from blogpost.core.views import core
from blogpost.user.views import users

# BLUEPRINTS CONFIGURATION #################################
app.register_blueprint(core)
app.register_blueprint(users)

and this is my models.py file.

from blogpost import db, login_manager
from flask_login import UserMixin
from datetime import datetime
from werkzeug.security import check_password_hash, generate_password_hash


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)


fav_posts = db.Table('fav_posts',
                     db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
                     db.Column('fav_posts_id', db.Integer, db.ForeignKey('posts.id')))

follows = db.Table('follows',
                   db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
                   db.Column('follows', db.Integer, db.ForeignKey('users.id')))

fav_tags = db.Table('fav_tags',
                    db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
                    db.Column('fav_tags_id', db.Integer, db.ForeignKey('tags.id')))

licked_posts = db.Table('licked_posts',
                        db.Column('post_id', db.Integer, db.ForeignKey('posts.id')),
                        db.Column('user_id', db.Integer, db.ForeignKey('users.id')))

tags_included = db.Table('tags_included',
                         db.Column('post_id', db.Integer, db.ForeignKey('posts.id')),
                         db.Column('user_id', db.Integer, db.ForeignKey('tags.id')))


class User(db.Model, UserMixin):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    email = db.Column(db.String, unique=True, index=True)
    dob = db.Column(db.Date)
    password_hash = db.Column(db.String)
    account_created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    profile_image = db.Column(db.String)
    is_verified = db.Column(db.Boolean, default=False)

    posts = db.relationship('Post', backref='author', lazy=True)
    favorite_posts = db.relationship('Post', secondary=fav_posts, backref=db.backref('fav_by', lazy='dynamic'))
    followers = db.relationship('User', secondary=follows, backref=db.backref('following', lazy='dynamic'))
    favorite_tags = db.relationship('Tag', secondary=fav_tags, backref=db.backref('users', lazy='dynamic'))

    def __init__(self, email, password, username, dob):
        self.email = email
        self.username = username
        self.dob = dob
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)


class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    body = db.Column(db.Text)
    date_created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)

    likes = db.relationship('User', secondary=licked_posts, backref=db.backref('licked_by', lazy='dynamic'))
    tags_includes = db.relationship('Tag', secondary=tags_included,
                                backref=db.backref('post_including_tag', lazy='dynamic'))

    def __init__(self, title, body):
        self.title = title
        self.body = body


class Tag(db.Model):
    __tablename__ = 'tags'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)

    def __init__(self, name):
        self.name = name

can anyone one tell me what should I do to solve this and more importantly what is the cause because I have done same in my previous project but this never happened.

UPDATE:-

I've solved this problem by creating my user_loader inside my init file after the login_manager.login_view = 'users.login' file. I imported the User model after this line and then created the user_loader.

so my guess is that the problem is that flask is not able to find the "models.py" file. if anyone can explain the problem accurately or have a better solution you're most welcome (^-^)

here is another work i did for practice and it worked fine.

#puppycompanyblog/__init__.py
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager

app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecretkey'

#DATABASE SETUP##########################
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir,'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATION'] = False

db = SQLAlchemy(app)
Migrate(app,db)
#########################################

#LOGIN CONFIGURATIONS####################
login_manager = LoginManager()

login_manager.init_app(app)
login_manager.login_view = 'users.login'
#########################################

from puppycompanyblog.core.views import core
from puppycompanyblog.users.views import users
from puppycompanyblog.blog_posts.views import blog_posts
from puppycompanyblog.error_pages.handlers import error_pages

app.register_blueprint(core)
app.register_blueprint(users)
app.register_blueprint(blog_posts)
app.register_blueprint(error_pages)

and

# puppycompanyblog/models.py
from puppycompanyblog import db, login_manager
from werkzeug.security import check_password_hash, generate_password_hash
from flask_login import UserMixin
from datetime import datetime


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)


class User(db.Model, UserMixin):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    profile_image = db.Column(db.String(64), nullable=False, default='default_profile.png')
    email = db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))

    posts = db.relationship('BlogPost', backref='author', lazy=True)

    def __init__(self, email, username, password, ):
        self.email = email
        self.username = username
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

    def __repr__(self):
        return f"username: {self.username}"


class BlogPost(db.Model):
    users = db.relationship(User)

    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)

    date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    title = db.Column(db.String(140), nullable=False)
    text = db.Column(db.Text, nullable=False)

    def __init__(self, title, text, user_id):
        self.title = title
        self.text = text
        self.user_id = user_id

    def __repr__(self):
        return f"Post ID: {self.id} -- Date: {self.date} --- {self.title}"

1 Answer 1

2

The reason why the user_loader function isn't found is because you are not importing the module in which it is defined. You put it in models.py, so you need to import this module somewhere in the area where you define your application, so that the handler is registered with the Flask-Login extension. You'll also need to import this file so that Flask-SQLAlchemy registers your models.

Based on the code that you posted, you could add import models at the bottom of blogpost/__init__.py and I think that should do it (it needs to be at the bottom to prevent circular imports).

Sign up to request clarification or add additional context in comments.

3 Comments

doesn't flask read models.py file automatically because in my other project i didn't need to import models.py file into the init.py file and it works fine.
Flask has no knowledge of your database, so no, it does not import models.py for you. If you did not need to import this file explicitly, then it must be imported indirectly in some other file.
I explained this in my answer. Sometimes the models get imported indirectly, and that explains why things work. In this last example you have a bunch of imports for views. Pretty sure one or more of those import the models.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.