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

ros*_*ssd 6 python login sqlalchemy flask 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'
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么我收到这个错误.用户从数据库中成功查询,并且用户在密码列中具有哈希密码.

我正在使用的查询和从密码列返回数据的方法类似于文档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')
Run Code Online (Sandbox Code Playgroud)

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

Bus*_*ust 17

@login_manager.user_loader
def user_loader(user_id):
    user = User.query.filter_by(id=user_id).first()
    if user:
        return user
    return None
Run Code Online (Sandbox Code Playgroud)

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

.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)
Run Code Online (Sandbox Code Playgroud)

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