为了账号安全,请及时绑定邮箱和手机立即绑定

新手学习Flask引用flask-login后登入错误原因不清

新手学习Flask引用flask-login后登入错误原因不清

慕尼黑8549860 2019-02-21 09:48:33
自己在学习Flask时,使用flask-login遇到问题。 程序是一个很简单的登录鉴权的程序,如果用户输入用户名和密码正确,则可以查看到首页,否则回到登录页面让用户输入用户名和密码。 目前遇到的问题是,输入错误的用户名和密码不可登录(正常),但输入正确的用户名和密码后,程序报错。 开启Flask调试模式,报错信息如下: builtins.TypeError TypeError: 'NoneType' object is not callable Traceback (most recent call last) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1836, in call return self.wsgi_app(environ, start_response) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1820, in wsgi_app response = self.make_response(self.handle_exception(e)) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1403, in handle_exception reraise(exc_type, exc_value, tb) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise raise value File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise raise value File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask/app.py", line 1461, in dispatch_request return self.view_functionsrule.endpoint File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask_login.py", line 756, in decorated_view elif not current_user.is_authenticated(): File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/werkzeug/local.py", line 338, in getattr return getattr(self._get_current_object(), name) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/werkzeug/local.py", line 297, in _get_current_object return self.__local() File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask_login.py", line 46, in current_user = LocalProxy(lambda: _get_user()) File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask_login.py", line 794, in _get_user current_app.login_manager._load_user() File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask_login.py", line 363, in _load_user return self.reload_user() File "/Users/duzhipeng/project/xianpi/venv/lib/python3.4/site-packages/flask_login.py", line 325, in reload_user user = self.user_callback(user_id) TypeError: 'NoneType' object is not callable The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error. To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side. You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection: dump() shows all variables in the frame dump(obj) dumps all that's known about the object 主程序就两个文件,源码分别如下: run.py # -*- coding: utf-8 -*- import os from flask import Flask, render_template, redirect, url_for, flash from flask.ext.sqlalchemy import SQLAlchemy from flask_wtf import Form from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired from flask.ext.login import LoginManager, login_required, login_user basedir = os.path.abspath(os.path.dirname(__file__)) app = Flask(__name__) app.config['SECRET_KEY'] = 'stong key' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////' + os.path.join(basedir, 'date.sqlite') app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True db = SQLAlchemy(app) login_manager = LoginManager(app) login_manager.session_protection = 'strong' login_manager.login_view = 'login' class LoginForm(Form): username = StringField('用户名', validators=[DataRequired()]) password = PasswordField('密码', validators=[DataRequired()]) submit = SubmitField() @app.route('/') @login_required def index(): return 'hello' @app.route('/login', methods=['GET', 'POST']) def login(): from models import Admin form = LoginForm() if form.validate_on_submit(): user = Admin.query.filter_by(username=form.username.data).first() if user is not None and user.verify_password(form.password.data): login_user(user) return redirect(url_for('index')) flash('用户名或密码错误') return render_template('login.html', form=form) if __name__ == '__main__': app.run(debug=True) models.py # -*- coding: utf-8 -*- from werkzeug.security import generate_password_hash, check_password_hash from flask.ext.login import UserMixin from run import db, login_manager class Admin(UserMixin, db.Model): __tablename__ = 'admin' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True) password_hash = db.Column(db.String(128), unique=False) @property def password(self): raise AttributeError('不能直接获取明文密码!') @password.setter def password(self, password): self.password_hash = generate_password_hash(password) def verify_password(self, password): return check_password_hash(self.password_hash, password) def __repr__(self): return "<Admin '{:s}>".format(self.username) @login_manager.user_loader def load_user(user_id): return Admin.query.get(int(user_id)) if __name__ == '__main__': db.create_all() 我自己觉得是login_manager.user_loader 回调有问题,user_id从哪里来的也弄不明白。 自己GG和看了例子大概3个小时了,还是无解,因此特来请大神解惑。 谢谢!
查看完整描述

1 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

自己知道错误在哪里了。

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

@login_manager.user_loader 写到models里了,导致没有被调用生效。改到run里就可以了。不过这和书上的不同,例子也不同。这点我还得研究研究。

查看完整回答
反对 回复 2019-03-01
  • 1 回答
  • 0 关注
  • 1114 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信