python - Flask-sqlalchemy - 用户查询 'BaseQuery' 对象没有属性 'password'

标签 python authentication flask sqlalchemy flask-sqlalchemy

我是 Python 和 Flask 新手。

我正在关注本教程 http://douglasstarnes.com/index.php/2015/05/27/easy-authentication-with-flask-login/拥有注册和登录页面,并对其进行了稍微修改,以在注册时对密码进行哈希处理,并根据登录时的哈希值验证密码。

初始密码注册哈希有效,但根据通过登录表单以纯文本形式给出的密码验证存储在数据库中的哈希密码则无效。

我收到的错误是针对/login 页面上的以下行,原因如下:

if user.count() == 1 and check_password_hash(user.password, password) == True:

AttributeError: 'BaseQuery' object has no attribute 'password'

我无法弄清楚为什么会收到此错误。成功从数据库查询用户,并且用户在密码列中拥有其哈希密码。

我正在使用的查询和从密码列返回数据的方法与文档 http://flask-sqlalchemy.pocoo.org/2.1/queries/#querying-records 中包含的类似。

这是我的views.py(/login 和错误行位于底部)

from flask import Flask, render_template, request, abort, redirect, url_for, flash
from flask.ext.login import LoginManager, UserMixin, login_user, logout_user, login_required
from flask.ext.sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from app import app
import os

login_manager = LoginManager(app)
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.session_protection = "strong"

db = SQLAlchemy(app)

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String)
    password = db.Column(db.String)

@login_manager.user_loader
def user_loader(user_id):
    user = User.query.filter_by(id=user_id)
    if user.count() == 1:
    return user.one()
    return None

@app.before_first_request
def init_request():
    db.create_all()

@app.route('/secret')
@login_required
def secret():
    return render_template('secret.html')

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
    return render_template('register.html')
    elif request.method == 'POST':
    username = request.form['txtUsername']
    password = request.form['txtPassword']
    user = User.query.filter_by(username=username)
    if user.count() == 0:
        hashed_password = generate_password_hash(password)
        user = User(username=username, password=hashed_password)
        db.session.add(user)
        db.session.commit()

        flash('You have registered the username {0}. Please login'.format(username))
        return redirect(url_for('login'))
    else:
        flash('The username {0} is already in use.  Please try a new username.'.format(username))
        return redirect(url_for('register'))
    else:
    abort(405)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
    return render_template('login.html', next=request.args.get('next'))
    elif request.method == 'POST':
    username = request.form['txtUsername']
    password = request.form['txtPassword']
    user = User.query.filter_by(username=username)
    if user.count() == 1 and check_password_hash(user.password, password) == True:
        login_user(user.one(), remember=True)
        flash('Welcome back {0}'.format(username))
        try:
            next = request.form['next']
            return redirect(next)
        except:
            return redirect(url_for('index'))
    else:
        flash('Invalid login')
        return redirect(url_for('login'))
    else:
    return abort(405)

@app.route('/')
def index():
    return render_template('index.html')

有谁知道为什么我无法访问用户的密码列,或者事实上任何列?我已经尝试了数据库、ID、用户名和密码中的所有 3 个。

最佳答案

@login_manager.user_loader
def user_loader(user_id):
    user = User.query.filter_by(id=user_id).first()
    if user:
        return user
    return None

应用.first()执行查询,而不是存储查询对象 它只会返回第一个结果。

.all() 返回全部

编辑:

或者你可以使用user = User.query.get(user_id)假设user_id被定义为PK

在您的登录功能中,它应该是

  user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password, password) == True:
        login_user(user)

现在用户引用真实的 User 对象,而不是存储的查询。您无法从查询对象访问用户对象属性(密码)

关于python - Flask-sqlalchemy - 用户查询 'BaseQuery' 对象没有属性 'password',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34795798/

相关文章:

python - 异常和 Python

c# - Windows 域登录可以包含超过 1 个 '\' 字符吗?

django - 使用中间件覆盖 Django 身份验证

python - 如何在浏览器地址栏中显示@而不是编码为%40(urlencode)?

python - 无法在 Webfaction 上部署简单的 Flask 应用程序

python - 将变量从 HTML 传递到 Python/Flask

python - 如何根据 dtype 删除 DataFrame 列

python - 如何在 django 模板中呈现有序字典?

python - 如何检查sqlite数据库中的用户名? Python

python - Discord.py 在游戏事件中发挥作用