Mongoengine creation_time attribute in Document

后端 未结 9 1327
Happy的楠姐
Happy的楠姐 2020-12-14 15:50

I am trying to add a creation_time attribute to my documents. The following would be an example:

import datetime

class MyModel(mongoengine.Docu         


        
相关标签:
9条回答
  • 2020-12-14 15:55

    One nice solution is reusing a single signal handler for multiple documents.

    class User(Document):
        # other fields...
        created_at = DateTimeField(required=True, default=datetime.utcnow)
        updated_at = DateTimeField(required=True)
    
    class Post(Document):
        # other fields...
        created_at = DateTimeField(required=True, default=datetime.utcnow)
        updated_at = DateTimeField(required=True)
    
    def update_timestamp(sender, document, **kwargs):
        document.updated_at = datetime.utcnow()
    
    signals.pre_save.connect(update_timestamp, sender=User)
    signals.pre_save.connect(update_timestamp, sender=Post)
    

    Be careful to assign a callable and not a fixed-value as the default, for example default=datetime.utcnow without (). Some of the other answers on this page are incorrect and would cause created_at for new documents to always be set to the time your app was first loaded.

    It's also always better to store UTC dates (datetime.utcnow instead of datetime.now) in your database.

    0 讨论(0)
  • 2020-12-14 15:58

    My preferred solution is to use the @property decorator to return the creation datetime as extracted from the ObjectId:

    @property
    def creation_stamp(self):
        return self.id.generation_time
    
    0 讨论(0)
  • 2020-12-14 16:02

    Try use lambda value:

    import datetime
    from mongoengine import Document
    
    class MyModel(Document):
        creation_date = mongo.DateTimeField()
        modified_date = mongo.DateTimeField(default=lambda : datetime.datetime.now())
    
    0 讨论(0)
  • 2020-12-14 16:12

    Traditionally, I've set the creation_date default to datetime.now() and then have hidden the field on the admin form so you remove the possibility of a user overwriting the correct value. That requires almost no code.

    Overriding the save method as suggested by Willian is also effective since you can programmtically block any updates to the creation_date and update the modfied_date at the same time.

    0 讨论(0)
  • 2020-12-14 16:13

    You could override the save method.

    class MyModel(mongoengine.Document):
        creation_date = mongo.DateTimeField()
        modified_date = mongo.DateTimeField(default=datetime.datetime.now)
    
        def save(self, *args, **kwargs):
            if not self.creation_date:
                self.creation_date = datetime.datetime.now()
            self.modified_date = datetime.datetime.now()
            return super(MyModel, self).save(*args, **kwargs)
    
    0 讨论(0)
  • 2020-12-14 16:13
    # -*- coding: utf-8 -*-
    from mongoengine import *
    from mongoengine import signals
    from datetime import datetime
    
    class User(Document):
        email = StringField(required=True, unique=True)
        first_name = StringField(max_length=50)
        last_name = StringField(max_length=50)
        # audit fields
        created_on = DateTimeField(default=datetime.now())
        updated_on = DateTimeField(default=datetime.now())
    
        @classmethod
        def pre_save(cls, sender, document, **kwargs):
            document.updated_on = datetime.now()
    
    signals.pre_save.connect(User.pre_save, sender=User)
    
    0 讨论(0)
提交回复
热议问题