5

I'm trying to make a fork of MongoEngine that will allow auto updating of a DateTimeField based on passing True to an auto_now or auto_now_add (a la Django).

So far I've added the attributes to the __init__ method of DateTimeField like so:

def __init__(self, auto_now=None, auto_now_add=None, **kwargs):
    self.auto_now, self.auto_now_add = auto_now, auto_now_add
    super(DateTimeField, self).__init__(**kwargs)

Unfortunately, I cannot figure out how to populate this value cleanly when a document is created/saved. The only solution I see so far, is to add field specific behavior in BaseDocument's save or validate methods... But I don't like it.

Does anyone know of a better method?

By the way: I though of having a go at this after reading this question and @equinoxel's comment about extending mongo and being used to this attribute in django.

Community
  • 1
  • 1
tutuDajuju
  • 10,307
  • 6
  • 65
  • 88

1 Answers1

17

You could add a pre save signal and update the document date before saving.

class MyDoc(Document):
    name = StringField()
    updated_at = DateTimeField(default=datetime.datetime.now)

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        document.updated_at = datetime.datetime.now()

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

The main issues with this is they wont be updated if you call update or if you do bulk updates eg: MyDocs.objects.update(set__name=X)

Added ticket: https://github.com/MongoEngine/mongoengine/issues/110

Ross
  • 17,861
  • 2
  • 55
  • 73
  • Thanks a lot. Although, I kind of knew I could do that (also [this answer](http://stackoverflow.com/a/11851794/484127) for [the question I linked above](http://stackoverflow.com/questions/8098122/mongoengine-creation-time-attribute-in-document) told me that) I appreciate the help. By the way, I just wanted to solve that ticket you opened and needed a push in the right direction :) – tutuDajuju Sep 04 '12 at 13:09
  • Well the question linked above overrides save which isnt great and misses the point about updates as well. So currently you have to handle it in your app. – Ross Sep 04 '12 at 13:14
  • yea, the accepted answer does, but the one I linked to (last in question page) suggests exactly what you have here - sorry for being anal about it... Still though, any idea how to go about solving this issue? Do you think it will require a dramatic change in how mongoengine handles save/update of documents? Like for instance, running a "prepare_fields" that will run in both save & update methods of document.py? – tutuDajuju Sep 04 '12 at 16:18
  • 1
    @Dajuju update can be done with clean() that is called before saving on mongo. – zeferino Aug 30 '13 at 15:42
  • 2
    It requires blinker library installed. `pip install blinker` [pypi/blinker](https://pypi.python.org/pypi/blinker) – Moreno Apr 16 '15 at 15:37
  • What's bad about overriding `save`? – Jérôme Jan 27 '16 at 17:15