更新'用户名'字段会将用户注销 (flask-login - MongoDB) - 类问题?

问题描述 投票:0回答:1

我正在使用flask应用(使用flask-login和PyMongo),我的用户有这个类,还有这个加载器(这是完整的user.py文件)。

from werkzeug.security import check_password_hash
from app import login, mongo

class User():
    def __init__(self, username, first_name, last_name, email, _id, is_admin):
        self.username = username
        self.first_name = first_name
        self.last_name = last_name
        self.email = email
        self._id = _id
        self.is_admin = is_admin

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return self.username

    @staticmethod
    def check_password(password_hash, password):
        return check_password_hash(password_hash, password)


@login.user_loader
def load_user(username):
    user = mongo.db.users.find_one({'username': username})
    if not user:
        return None
    return User(user['username'], user['first_name'], user['last_name'], user['email'], user['_id'], user['is_admin'])

注册,登录和注销路径工作正常,但我的update_account路径有问题,它更新了用户信息。我可以更新数据库中的所有字段,但当我更新时 ‘username’ 我被注销了,或者说是注销后被重定向到了 /login?next=%2Faccount HTTP (尽管字段得到正确的更新).我意识到我的类有问题,所以我试着修改它的结尾和加载器,通过用 _id,如。

class User():
    def __init__(self, username, first_name, last_name, email, _id, is_admin):
        self.username = username
        self.first_name = first_name
        self.last_name = last_name
        self.email = email
        self._id = _id
        self.is_admin = is_admin


    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return self._id

@login.user_loader
def load_user(_id):
    user = mongo.db.users.find_one({'_id': _id})
    if not user:
        return None
    return User(user['username'], user['first_name'], user['last_name'], user['email'], user['_id'] , user['is_admin'])

但是,我得到一个 TypeError: Object of type ObjectId is not JSON serializable.

额外的信息。当我更新任何其他字段时,我在我的控制台中正确地得到:

127.0.0.1 - -"POST /account HTTP/1.1" 302 -
127.0.0.1 - -"GET /account HTTP/1.1" 200 -

但是更新用户名会引起:

127.0.0.1 - -"POST /account HTTP/1.1" 302 -
127.0.0.1 - -"GET /account HTTP/1.1" 302 -
127.0.0.1 - -"GET /login?next=%2Faccount HTTP/1.1" 200 -

如果能帮上忙的话,这是我编辑账户的途径。 In case it helps, this is my route to edit the account:

@app.route('/account', methods=['POST', 'GET'])
@login_required
def account():
    form = UpdateAccountForm()
    updated_user = {'username': form.username.data, 'first_name': form.first_name.data,
                    'last_name': form.last_name.data, 'email': form.email.data}
    if form.validate_on_submit():
        mongo.db.users.update_one(
            {'_id': current_user._id}, {"$set": updated_user})
        flash('Updated!', 'info')
        return redirect(url_for('account'))
    elif request.method == 'GET':
        form.username.data = current_user.username
        form.first_name.data = current_user.first_name
        form.last_name.data = current_user.last_name
        form.email.data = current_user.email
    return render_template('account.html', title="About", form=form)

你们谁能帮我解决这个问题?谢谢你!

python mongodb flask flask-login
1个回答
1
投票

这个 _id 字段在pymongo中被表示为ObjectId实例(从 bson 库)。)

要么从违规函数中删除这个字段,要么先把它转换为字符串。


0
投票

我在更新的时候,在同一条路由内,立即登录用户,就解决了这个问题。所以有点后端技巧,但用户是察觉不到的。

© www.soinside.com 2019 - 2024. All rights reserved.