0

How can I execute some code only when a document is created in mongoengine, not when updated.

class Account(Document):
    name = StringField(max_length=80, default=None)
    username = StringField(max_length=60, required=True)
    created_at = DateTimeField(default=datetime.now(), required=True)
    updated_at = DateTimeField(default=datetime.now(), required=True)

    meta = {
        'collection': 'accounts'
    }

Now I want to generate random username and assign it to the username field before a document is created.

Any help is appreciated. Thanks.

Rohit Khatri
  • 1,980
  • 3
  • 25
  • 45

1 Answers1

1

You should use one of the MongoEngine's signals - pre_save() sounds like a good fit. There are different ways to attach an event handler to a signal, here is one of them:

from mongoengine import signals

class Account(Document):
    # ...

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        document.username = "random username"

signals.pre_save.connect(Account.pre_save, sender=Account)
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • I think `pre_save` is called while updating as well, and I don't want to execute my code every time document is saved, just once when It's created. – Rohit Khatri Dec 19 '16 at 06:22
  • @RohitKhatri ah, gotcha..then `pre_init()` might be a good fit. – alecxe Dec 19 '16 at 06:23
  • how can I access the document fields in pre_init signal handler, because when I try to access document property name, It throws error `AttributeError: _data` – Rohit Khatri Dec 19 '16 at 07:16
  • @RohitKhatri I've not personally used `pre_init()` before and expected setting the fields via `document.field` work..okay, can you try with `post_init()`? Thanks. – alecxe Dec 19 '16 at 11:20
  • I accomplished this by using `post_init` and executed my code If the `document.id` is `None` – Rohit Khatri Dec 19 '16 at 11:23