我有一个Flask应用程序,我正在编写使用Flask测试的测试。我在运行应用程序和登录/注销时没有遇到任何问题,但是为登录功能编写测试已经适得其反。我收到以下错误:"异常:没有为此LoginManager安装user_loader。使用' LoginManager.user_loader'添加一个。装饰#&34;但是,我在User模型中定义了一个user_loader装饰器(请参阅此flask-login example)。知道什么是错的吗?
我的代码是:
models.py中的用户模型:
from flask_login import UserMixin
from sqlalchemy.orm import relationship, backref
from werkzeug.security import generate_password_hash, check_password_hash
from app import db, login_manager
class User(UserMixin, db.Model):
"""
Create a User table
"""
# Ensures table will be named in plural and not in singular
# as is the name of the model
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(60), index=True, unique=True)
username = db.Column(db.String(60), index=True, unique=True)
first_name = db.Column(db.String(60), index=True)
last_name = db.Column(db.String(60), index=True)
password_hash = db.Column(db.String(128))
is_admin = db.Column(db.Boolean, default=False)
file = db.relationship('File', backref='users')
@property
def password(self):
"""
Prevent password from being accessed
"""
raise AttributeError('password is not a readable attribute.')
@password.setter
def password(self, password):
"""
Set password to a hashed password
"""
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
"""
Check if hashed password matches actual password
"""
return check_password_hash(self.password_hash, password)
# Set up user_loader
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
def __repr__(self):
return '<User: {}>'.format(self.username)
初始化的.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_migrate import Migrate
from flask_bootstrap import Bootstrap
from flask_debugtoolbar import DebugToolbarExtension
from flask_uploads import UploadSet, DOCUMENTS, DATA, configure_uploads
# local imports
from config import app_config
# db variable initialization
db = SQLAlchemy()
login_manager = LoginManager()
login_manager.login_message = "You must be logged in to access this page."
login_manager.login_view = "auth.login"
def create_app(config_name):
app = Flask(__name__, instance_relative_config=True)
app.config.from_object(app_config[config_name])
app.config.from_pyfile('config.py')
db.init_app(app)
# Code for login manager
login_manager.init_app(app)
# Code for db migrations
migrate = Migrate(app, db)
# Bootstrap
Bootstrap(app)
# Debugger
DebugToolbarExtension(app)
# # Configure the data uploading via Flask-Uploads
# data_set = UploadSet('data_set', DOCUMENTS, DATA)
# configure_uploads(app, data_set)
from app import models
# Register Blueprints
from .admin import admin as admin_blueprint
app.register_blueprint(admin_blueprint, url_prefix='/admin')
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
from .home import home as home_blueprint
app.register_blueprint(home_blueprint)
return app
tests.py
from flask import Flask
from flask import url_for
from flask_sqlalchemy import SQLAlchemy
from flask_testing import TestCase
import app.__init__ as app_init
from app import db, login_manager
from app.models import User
class RenderbotTestCase(TestCase):
def create_app(self):
app = app_init.create_app('testing')
app.config.update(
SQLALCHEMY_DATABASE_URI = 'mysql://testingdburl'
)
return app
def setUp(self):
self.c = self.app.test_client()
db.init_app(self.app)
db.create_all()
self.first_user = User(email="test@test.com",
username="Test",
first_name="Tom",
last_name="Test",
password="test")
db.session.add(self.first_user)
db.session.commit()
def tearDown(self):
db.session.remove()
db.drop_all()
def login(self, email, password):
return self.c.post(url_for('auth.login'), data=dict(
email=email,
password=password
), follow_redirects=True)
def test_login(self):
rv = self.login('test@test.com', 'test')
self.assert_redirects(rv, url_for('home.dashboard')), 'Unable to login'