I am using flask-mongoengine extension and I have a User class like this:
class User(db.Document, UserMixin):
email = db.StringField(max_length=120,
Try downgrading pymongo.
pip install pymongo==2.8
I was getting this error no matter what and the only way I fixed it was to downgrande pymongo from 3.0 to 2.8.
I know what happened on you code. you should use __str__ instead of using __init__ I have the same problem .now I have solved it . hope I can help you !
I don't know why but I was also keep getting the same error and only after downgrading pymongo from 3.0 to 2.8 it got fixed as David mentioned.
Pymongo should publish a fix for that, it is frustrating and made me waste couple of hours before realizing it.
This because when mongoengine get data from database then it create instance like User(**data)
(there are also can be problem with id
). So you haven't required password
argument there:
{
'id': ObjectId('51b349aef5ddaf191f2fb12f'),
u'email': u'test@test.test',
u'password_hash': u'12345678123456781234567812345678'
}
Try next User
class implementation:
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)
I have next implementation for my project:
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)