Обновление поля 'username' выводит пользователя из системы (flask -login - MongoDB) - Проблема класса? - PullRequest
2 голосов
/ 03 мая 2020

Я работаю над моим flask приложением (использующим flask -login и PyMon go) и имею этот класс для моего пользователя и этого загрузчика (это полный файл users.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 -

В Если это поможет, это мой маршрут для редактирования учетной записи:

@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)

Может ли кто-нибудь из вас помочь мне разобраться в этом? Спасибо !!

1 Ответ

1 голос
/ 03 мая 2020

Поле _id представлено в pymon go как экземпляр ObjectId (из библиотеки bson).

Либо удалите это поле из функции-нарушителя, либо сначала преобразуйте его в строку.

...