AttributeError: 'dict' 对象没有属性 'is_active' (PyMongo 和 Flask)

AttributeError: 'dict' object has no attribute 'is_active' (PyMongo And Flask)

提问人:Usman Rafiq 提问时间:11/21/2018 更新时间:11/21/2018 访问量:4724

问:

@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        users = mongo.db.users
        hash_password=bcrypt.generate_password_hash(form.password.data).decode('utf-8')
        eml=form.email.data
        gen=form.gender.data
        ctry=form.country.data
        profile={'name' : form.username.data, 'password' :hash_password,'email':eml,'gender':gen,'country':ctry}
        users.insert(profile)
        #users.insert({'name' : form.username.data, 'password' :form.password.data})
        flash(f'Your has been Account created for Username {form.username.data}!, You can login', 'success')
        return redirect(url_for('login'))
        #return redirect(url_for('home'))
    return render_template('register.html', title='Register', form=form)

@app.route("/login", methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        users = mongo.db.users
        loginuser = users.find_one({'email' : form.email.data})
        if loginuser and bcrypt.check_password_hash(loginuser['password'],form.password.data):
        #if form.email.data == '[email protected]' and form.password.data == 'password':
            login_user(loginuser,remember=form.data.remember)
            return redirect(url_for('home'))
            #flash('You have been logged in!', 'success')
            #return redirect(url_for('home'))
        else:
            flash('Login Unsuccessful. Please check username and password', 'danger')
    return render_template('login.html', title='Login', form=form)

我使用带有 pymongo 组合的 flask 创建了一个简单的注册和登录方法。 现在对于用户会话管理,我正在使用 flask_login 但它给了我这个错误 AttributeError:“dict”对象没有属性“is_active”

我发现不同的解决方案是在UserClass中添加UserMaxIn 但是我没有任何用户模型类,我也不想做它

这个错误的解决方案是什么?

python flask pymongo flask-登录

评论


答:

3赞 vinsce 11/21/2018 #1

Flask-Login 要求您使用类来表示用户,而不是原始字典。

文档中所述,此类需要实现一些属性和方法,包括该方法。is_active()

该类是为所有必需的属性和方法提供默认实现的基类,您可以扩展它并创建一个简单的 User 类。UserMixin


更新:添加了示例

根据您已经拥有的内容,您可以做的最简单的事情是:

  • 创建扩展的自定义类UserUserMixin
  • 将 MongoDB 中的对象存储在类中jsonUser
  • 覆盖需要与默认行为不同的方法
  • 在路由中,创建类的实例并将其传递给/loginUserflask_login.login_user()

User 类

class User(UserMixin):
    def __init__(self, user_json):
        self.user_json = user_json

    # Overriding get_id is required if you don't have the id property
    # Check the source code for UserMixin for details
    def get_id(self):
        object_id = self.user_json.get('_id')
        return str(object_id)

对于所有方法/属性 (, , ),除非它使用默认实现。如果你不需要默认的实现,你不需要扩展,但你必须自己实现所有的方法。is_authenticatedis_activeis_anonymousget_idUserMixin

用户类在登录路由中的用法

@app.route("/login", methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        users = mongo.db.users
        loginuser_json = users.find_one({'email': form.email.data})
        if loginuser_json and bcrypt.check_password_hash(loginuser_json['password'], form.password.data):
            # Create a custom user and pass it to login_user:
            loginuser = User(loginuser_json)
            login_user(loginuser, remember=form.data.remember)
            return redirect(url_for('home'))
        else:
            flash('Login Unsuccessful. Please check username and password', 'danger')
    return render_template('login.html', title='Login', form=form)

请记住,您还必须提供此处所述的。例如,给定 ,在 MongoDB 上执行查询并返回对象:user_loaderuser_idUser

@login_manager.user_loader
def load_user(user_id):
    users = mongo.db.users
    user_json = users.find_one({'_id': ObjectId(user_id)})
    return User(user_json)

相关链接

评论

0赞 Usman Rafiq 11/21/2018
你能给我一个简单的代码来创建 User 类吗?以及如何在登录路由中调用该类
0赞 Usman Rafiq 11/21/2018
谢谢很多,它的工作顺便说一句,如何获取当前用户的电子邮件?
0赞 vinsce 11/21/2018
您可以从 json 对象中获取它: .如果要从对象中获取它:,或者可以在类中添加一个新方法。loginuser_json.get('email')Useruser_object.user_json.get('email')get_emailUser
0赞 Usman Rafiq 11/21/2018
def get_mail(self): object_id = self.user_json.get('email') return str(object_id) 像这样?
0赞 vinsce 11/21/2018
是的,它可以工作,但电子邮件已经是字符串,因此您可以简单地:def get_mail(self): return self.user_json.get('email')