查询MySQL用户时触发AttributeError:'list'对象无'password'属性
问题原因分析
你遇到的AttributeError: 'list' object has no attribute 'password',本质是因为connectToMySQL的query_db方法返回的是包含字典的列表——哪怕查询结果只有一条数据,它也会把字典包装在列表里返回。你打印看到的字典其实是列表里的第一个元素,但你直接把user_in_db当成字典来访问.password,自然触发报错。
实际返回的结构是类似这样的列表:
[{'id': 1, 'first_name': 'Eric', 'last_name': 'Fallon', 'email': 'ericmfal@gmail.com', 'password': '#hashedpassword', 'updated_at': datetime.datetime(2023, 6, 8, 18, 5, 57), 'created_at': datetime.datetime(2023, 6, 8, 18, 5, 57)}]
解决方法
两种可行修改方式,选其一即可:
方式一:修改User.get_by_email类方法
让类方法直接返回单个用户字典(如果存在),同时处理空结果的情况:
@classmethod def get_by_email(cls, data): query = 'SELECT * FROM users WHERE email = %(email)s;' results = connectToMySQL('pet_log').query_db(query, data) # 有结果则返回第一个字典,无结果返回None return results[0] if results else None
方式二:在登录路由中处理列表
保持类方法不变,在路由里手动取列表的第一个元素,同时注意字典用键访问而非属性访问:
@app.route('/login', methods=['post']) def login(): data = {'email':request.form['email']} user_results = User.get_by_email(data) if not user_results: flash('Email does not have an associated account.', 'login') return redirect('/') # 提取列表中的第一个用户字典 user_in_db = user_results[0] if not bcrypt.check_password_hash(user_in_db['password'], request.form['password']): flash('Invalid email/password combination.', 'login') return redirect('/')
补充说明
你之前项目代码能正常运行,大概率是因为当时使用的query_db方法在单条结果时直接返回字典,而当前项目的query_db实现是统一返回列表。对比两个项目中connectToMySQL的query_db方法实现就能确认差异。
内容的提问来源于stack exchange,提问作者Eric Fallon
相关产品推荐
相关产品推荐

