0

I have been testing mongoengine. I want to update some fields of a document and know which ones have been changed using the pre_save method

I have the following document

from mongoengine import Document, StringField, EmailField, IntField, signals
import bcrypt

class Users(Document):
  name = StringField(required=True)
  mail = EmailField(required=True, unique=True)
  age = IntField(required=True, default=0)
  password = StringField(min_length=7, required=True)

  @classmethod
  def pre_save(cls, sender, document, **kwargs):
    # if password.isChanged(): <-- How can I get this?
    #    document.password = bcrypt(document.password, "randonSalt")



signals.pre_save.connect(Users.pre_save, sender=Users)

I tried accessing document._changed_fields, but it shows up as an empty array

Thank you all

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158

1 Answers1

1

It's not the best practice to use methods starts from _, but Document has protected method document._delta(). The methods returns values that have been explicitly changed.

class Users(Document):
    name = StringField(required=True)
    mail = EmailField(required=True, unique=True)
    age = IntField(required=True, default=0)
    password = StringField(min_length=7, required=True)

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        updates, removals = document._delta()
        if 'password' in updates:
            print('new not saved password:', updates['password'])
        else:
            print('password isn\'t changed')

signals.pre_save.connect(Users.pre_save, sender=Users)

Usage example:

>> user = Users(name='uname', mail='some@gmail.com', age=2, password='secret0').save()
new not saved password: secret0

>> user.name = 'Name'
>> user.password = 'super-secret'
>> user.save()
new not saved password: super-secret

>> user.name = 'New Name'
>> user.save()
password isn't changed
Peter
  • 1,223
  • 3
  • 11
  • 22