【问题标题】:missing user_loader error exception in flask app烧瓶应用程序中缺少 user_loader 错误异常
【发布时间】:2020-07-25 14:10:24
【问题描述】:

我正在尝试创建一个基本的博客文章网站。一切都很顺利,直到我尝试运行该应用程序并显示错误:-

“例外:缺少 user_loader 或 request_loader”

但我已经创建了 user_loader。所以我试图找到解决方案,在这个过程中我发现flask db migrate 没有创建任何表。所以我在网上搜索并找到了一个解决方案,将我所有的表添加到迁移文件夹中的 evn.py 文件中。我认为这是问题所在,我尝试再次运行该应用程序并再次出现:-

“例外:缺少 user_loader 或 request_loader”

这是我的 __init__py 文件

# 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)

这是我的 models.py 文件。

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

谁能告诉我我应该怎么做才能解决这个问题,更重要的是是什么原因,因为我在以前的项目中做过同样的事情,但从未发生过。

更新:-

我通过在 login_manager.login_view = 'users.login' 文件之后的 init 文件中创建 user_loader 解决了这个问题。我在这一行之后导入了 User 模型,然后创建了 user_loader。

所以我的猜测是问题在于烧瓶无法找到“models.py”文件。如果有人可以准确地解释问题或有更好的解决方案,欢迎您(^-^)

这是我为练习所做的另一项工作,效果很好。

#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)

# 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}"

【问题讨论】:

    标签: python flask flask-sqlalchemy flask-login flask-migrate


    【解决方案1】:

    找不到 user_loader 函数的原因是你没有导入定义它的模块。你把它放在models.py,所以你需要在你定义你的应用程序的区域的某个地方导入这个模块,以便处理程序注册到 Flask-Login 扩展。您还需要导入此文件,以便 Flask-SQLAlchemy 注册您的模型。

    根据您发布的代码,您可以在blogpost/__init__.py 的底部添加import models,我认为应该这样做(它需要在底部以防止循环导入)。

    【讨论】:

    • 不会烧瓶自动读取 models.py 文件,因为在我的其他项目中我不需要将 models.py 文件导入 init.py 文件并且它可以工作很好。
    • Flask 不知道您的数据库,所以不,它不会为您导入 models.py。如果您不需要显式导入此文件,则必须将其间接导入到其他文件中。
    • 我在回答中解释了这一点。有时模型会间接导入,这就解释了为什么会起作用。在最后一个示例中,您有一堆视图导入。很确定其中一个或多个导入模型。
    猜你喜欢
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 2016-12-04
    • 2022-01-21
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    相关资源
    最近更新 更多