使用Flask-Login的UserMixin时出现'id'属性未找到错误求助
问题分析与解决
第一个错误原因
你在user_loader函数里的写法完全错误:
@login_manager.user_loader def load_user(id): return User.get_id(id)
get_id()是实例方法,只能由User类的实例调用,不能直接用类User去调用。而且user_loader的职责是根据传入的用户ID字符串,查询并返回对应的User实例,不是调用get_id方法。
第二个错误原因
当你重写get_id后,依然没修正user_loader的核心逻辑,导致返回的不是User实例,而是字符串(比如误调用get_id返回了id字符串),后续Flask-Login尝试访问这个字符串的id属性,自然抛出AttributeError: 'str' object has no attribute 'id'。
正确实现方式
1. 修正user_loader函数
user_loader需要把传入的字符串ID转为整数(因为你的User.id是Integer类型),然后查询数据库返回User实例:
@login_manager.user_loader def load_user(id): # Flask-Login传入的id是字符串,要转成整数匹配数据库的Integer类型 return User.query.get(int(id))
2. 关于get_id方法
你的User类已经继承了UserMixin,并且已经定义了id主键字段,不需要重写get_id方法。UserMixin的get_id默认实现会自动返回实例的id属性,完全满足需求。
如果确实需要自定义(比如用其他字段作为用户标识),才需要重写,正确的重写方式是:
def get_id(self): return str(self.id) # 返回字符串类型,符合Flask-Login要求
但在你的场景下,这一步是多余的,直接用UserMixin的默认实现即可。
最终的User类和user_loader示例
from flask_login import UserMixin from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base, UserMixin): __tablename__ = 'users' id = Column(Integer, primary_key=True) email = Column(String(70), unique=True) userName = Column(String(40), unique=True) password = Column(String(150)) # 不需要重写get_id,UserMixin已经帮你实现了
@login_manager.user_loader def load_user(id): return User.query.get(int(id))
关键要点总结
user_loader的核心是查询并返回User实例,不是调用get_id方法。- Flask-Login传入的id是字符串类型,要根据数据库字段类型做转换(比如转成整数)。
- 继承
UserMixin且有id字段时,无需重写get_id,默认实现即可正常工作。
内容的提问来源于stack exchange,提问作者Manoga
相关产品推荐
相关产品推荐

