Mongoengine AttributeError

Я пытаюсь закодировать авторизацию для приложения, используя Flask-Mongoengine и Flask-Login. И я получаю эту странную ошибку:

File "/usr/lib/python3.5/site-packages/mongoengine/base/document.py", line 188, in __setattr__
    super(BaseDocument, self).__setattr__(name, value)
  File "/usr/lib/python3.5/site-packages/mongoengine/base/fields.py", line 132, in __set__
    if instance._initialised:
AttributeError: _initialised

Мои модели.py:

from app import app, db
from flask.ext.login import LoginManager


login_manager = LoginManager()
login_manager.init_app(app)


class User(db.Document):
    email = db.StringField(required=True)
    first_name = db.StringField(max_lenght=40, required=True)
    last_name = db.StringField(max_lenght=40, required=True)
    password = db.StringField(required=True)

    def __init__(self, email, first_name, last_name, password):
        self.email = email
        self.first_name = first_name
        self.last_name = last_name
        self.password = password

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

   def get_id(self):
        return self.email

Я пробовал управлять классом, но это не помогло.

https://github.com/MongoEngine/flask-mongoengine/issues/156


person Tigran    schedule 14.07.2016    source источник
comment
У вас есть какие-либо обновления или исправления по этому поводу?   -  person trnc    schedule 30.07.2016


Ответы (3)


Mongoengine не требует, чтобы вы определяли __init__.

class User(db.Document):
    email = db.StringField(required=True)
    first_name = db.StringField(max_lenght=40, required=True)
    last_name = db.StringField(max_lenght=40, required=True)
    password = db.StringField(required=True)

    def clean(self):
        # clean will be called when you call .save()
        # You can do whatever you'd like to clean data before save
        self.password = str(self.password)

Тогда все, что вам нужно сделать, это

user = User(email='email@gmail', first_name='hello', last_name='there', password=2342143213)
user.save()
print(user.id)
person knittledan    schedule 28.10.2016

Исправление этой проблемы заключается в том, что вам нужно вызвать конструктор суперкласса, подобный этому

class User(db.Document):
    email = db.StringField(required=True)
    first_name = db.StringField(max_lenght=40, required=True)
    last_name = db.StringField(max_lenght=40, required=True)
    password = db.StringField(required=True)

    def __init__(self, email, first_name, last_name, password, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)
        self.email = email
        self.first_name = first_name
        self.last_name = last_name
        self.password = password

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

   def get_id(self):
        return self.email
person Gaurav Agarwal    schedule 06.08.2016

Будущие читатели должны знать, что в ответе knittledan clean() вызывается перед каждым save() вызовом, поэтому если он используется для хеширования поля пароля в модели, например:

def clean(self):
    self.password = bcrypt.generate_password_hash(self.password).decode('utf-8')

пароль будет постоянно переопределяться, что-то нежелательное. Обходной путь — использовать дополнительное поле, например: password_hashed = db.BooleanField(default=False)

def clean(self):
    if not self.password_hashed:
        self.password        = bcrypt.generate_password_hash(self.password).decode('utf-8')
        self.password_hashed = True
person Javier López    schedule 20.03.2018