0

If I have a class like:

class UpdateDocument(Document):
    modified_date = DateTimeField()
    meta = {'allow_inheritance': True}

    def save(self, *args, **kwargs):
        self.modified_date = datetime.utcnow()
        return super(UpdateDocument, self).save(*args, **kwargs)

this won't work because if it's inherited by another document, it won't be able to save itself to its own class, like:

 class New(UpdateDocument):
      name = StringField()

when you save it, it'll be inserted into the database as an UpdateDocument. What's the workaround to generalize the save method. This is part of the issue of updating indexes as well, but I'm more concerned with just balancing class inheritance.

Rob
  • 3,333
  • 5
  • 28
  • 71

1 Answers1

1

One solution is to use the signals capability in mongoengine. From the docs:

from datetime import datetime

from mongoengine import *
from mongoengine import signals

def update_modified(sender, document):
    document.modified = datetime.utcnow()

class Record(Document):
    modified = DateTimeField()

signals.pre_save.connect(update_modified)

This will apply the update_modified method to all documents before they are saved. You can also use class methods as per the docs:

class Author(Document):
    name = StringField()

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        logging.debug("Pre Save: %s" % document.name)

    @classmethod
    def post_save(cls, sender, document, **kwargs):
        logging.debug("Post Save: %s" % document.name)
        if 'created' in kwargs:
            if kwargs['created']:
                logging.debug("Created")
            else:
                logging.debug("Updated")

signals.pre_save.connect(Author.pre_save, sender=Author)
signals.post_save.connect(Author.post_save, sender=Author)
Steve Rossiter
  • 2,624
  • 21
  • 29
  • could you clarify where you'd place signals.pre_save? How does this attach to Record? – Rob Nov 28 '16 at 11:52
  • `signals.pre_save` can go wherever really best to keep it with the class definitions. I've added the `classmethod` approach as well. – Steve Rossiter Nov 29 '16 at 12:43