in Mongoengine 0.7.10, I can still do things like:
class User(db.Document):
email = db.EmailField(unique=True, required=True)
_password = db.StringField(max_length=255, required=True)
@property
def password(self):
return self._password
@password.setter
def password(self, password):
self._password = bcrypt.generate_password_hash(password)
user = User(email='[email protected]', password='12345')
However, the above code breaks in 0.8.0:
ValidationError: ValidationError (User:None) (_password.Field is required: ['User'])
It seems that MongoEngine doesn't recognised my custom password setter during initiation. I have to manually write these to fix it:
user = User(email='[email protected]')
user.password='12345'
This is probably due to the below changes(from Mongonengine 0.8 upgrading notes):
Previously, if you had data the database that wasn’t defined in the Document definition, it would set it as an attribute on the document. This is no longer the case and the data is set only in the document._data dictionary:
I would like to know if this is intended or is it a bug in MongoEngine? What is the best practice to write the custom property setter in my model?
Try this code:
class User(db.Document):
email = db.EmailField(unique=True, required=True)
_password = db.StringField(max_length=255, required=True, db_field='password')
def __init__(self, *args, **kwargs):
db.Document.__init__(self, *args, **kwargs)
if 'password' in kwargs:
self.password = kwargs['password']
@property
def password(self):
return self._password
@password.setter
def password(self, password):
self._password = bcrypt.generate_password_hash(password)
user = User(email='[email protected]', password='12345')
It works for me.
You should use the Document clean
function, described in the mongoengine documentation.
class User(db.Document):
email = db.EmailField(unique=True, required=True)
password = db.StringField(max_length=255, required=True)
def clean(self):
if not hashed(self.password):
self.password = bcrypt.generate_password_hash(self.password)
def hashed(self, password):
return # boolean check of whether the password is already hashed
user = User(email='[email protected]', password='12345')
user.save()
Every time you call user.save()
, it will now check if your password resembles a hashed value, and if not, hash it before updating the database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With