Mongoengine: TypeError: __init__() получил неожиданный аргумент ключевого слова

Я использую расширение flask-mongoengine, и у меня есть такой класс User:

class User(db.Document, UserMixin):     
    email = db.StringField(max_length=120, required=True, unique=True)
    password_hash = db.StringField(max_length=80, required=True)   
    active = db.BooleanField()
    fb_id = db.StringField(max_length=120, required=False)

    def __init__(self, email, password, fb_id=None, active=True):           
        hashp = md5.md5(password).hexdigest()        
        self.email=email
        self.password_hash=hashp
        self.fb_id=fb_id
        self.active=active

Но когда я делаю простое получение: User.objects.get(email = email)

Я получаю сообщение об ошибке:

TypeError: __init__() got an unexpected keyword argument 'password_hash'

но я устанавливаю password_hash в своем инициализаторе. Удивительно, но если я удалю все __init__ и передам все аргументами, все будет работать нормально.

Итак, я думаю, что я делаю что-то неправильно в __init__, может быть, что-то из-за суперкласса документа? Я очень застрял в этом, буду признателен за вашу помощь.


person Houman    schedule 07.06.2013    source источник
comment
как вы сохраняете/создаете нового пользователя? можешь показать этот код?   -  person codegeek    schedule 07.06.2013


Ответы (4)


Это потому, что когда mongoengine получает данные из базы данных, он создает экземпляр типа User(**data) (также могут быть проблемы с id). Таким образом, вам не требуется аргумент password:

{
    'id': ObjectId('51b349aef5ddaf191f2fb12f'), 
    u'email': u'[email protected]',
    u'password_hash': u'12345678123456781234567812345678'
}

Попробуйте следующую реализацию класса User:

class User(db.Document, UserMixin):
    email = db.StringField(max_length=120, required=True, unique=True)
    password_hash = db.StringField(max_length=80, required=True)
    active = db.BooleanField()
    fb_id = db.StringField(max_length=120, required=False)

    def __init__(self, password=None, **data):
        if password is not None:
            data['password_hash'] = md5.md5(password).hexdigest()
        super(User, self).__init__(**data)

У меня есть следующая реализация для моего проекта:

class User(db.Document, UserMixin):
    email = EmailField(unique=True, max_length=64, required=True)
    __password = StringField(db_field='password',
                             min_length=HASH_HEX_STRING_LENGTH,
                             max_length=HASH_HEX_STRING_LENGTH,
                             required=True)
    __password_salt = StringField(db_field='password_salt',
                                  min_length=DEFAULT_STRING_LENGTH,
                                  max_length=DEFAULT_STRING_LENGTH,
                                  required=True)

    def update_password(self, password):
        self.__password_salt = get_random_string(DEFAULT_STRING_LENGTH)
        self.__password = get_hash(password + self.__password_salt)
        return self

    def verify_password(self, password):
        return self.__password == get_hash(password + self.__password_salt)
person tbicr    schedule 08.06.2013

Попробуйте понизить версию pymongo.

pip install pymongo==2.8

Я получал эту ошибку, несмотря ни на что, и единственный способ исправить это — понизить pymongo с 3.0 до 2.8.

person David    schedule 12.04.2015

Я знаю, что случилось с вашим кодом. вы должны использовать __str__ вместо использования __init__ У меня та же проблема. Теперь я ее решил. надеюсь, что я могу помочь вам!

person Chao Yang    schedule 18.08.2015

Я не знаю почему, но я также продолжал получать ту же ошибку, и только после понижения версии pymongo с 3.0 до 2.8 она была исправлена, как упоминал Дэвид.

Pymongo должен опубликовать исправление для этого, это расстраивает и заставило меня потратить пару часов, прежде чем осознать это.

person ykorkmaz    schedule 28.08.2015