Атрибут времени создания Mongoengine в документе
Я пытаюсь добавить creation_time
атрибут для Моих документов. Следующий пример:
import datetime
class MyModel(mongoengine.Document):
creation_date = mongo.DateTimeField()
modified_date = mongo.DateTimeField(default=datetime.datetime.now)
модели Django имеют встроенный параметр для их DateTimeField
объекты типа add_now
, etc.,
но MongoEngine не поддерживает это.
мне интересно, если лучший способ сделать это следующим образом:
m,created = MyModel.objects.get_or_create()
if created:
m.creation_date = datetime.datetime.now()
или если есть лучший, лучший способ.
8 ответов
вы можете переопределить метод save.
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)
# -*- 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)
одним из хороших решений является повторное использование одного обработчика сигнала для нескольких документов.
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)
будьте осторожны, чтобы назначить вызываемое, а не фиксированное значение по умолчанию, например default=datetime.utcnow
без ()
. Некоторые из других ответов на этой странице неверны и вызовут created_at
для новых документов всегда устанавливается время первой загрузки приложения.
также всегда лучше хранить даты UTC (datetime.utcnow
вместо datetime.now
) в базе данных.
мое предпочтительное решение-использовать @property
декоратор для возврата datetime создания, извлеченного из ObjectId:
@property
def creation_stamp(self):
return self.id.generation_time
Если вы используете поле timestamp в куче документов, вы можете сохранить свой код сухой создать абстрактный документ.
from datetime import datetime
from mongoengine import Document
class CreateUpdateDocument(Document):
meta = {
'abstract': True
}
# last updated timestamp
updated_at = DateTimeField(default=datetime.now)
# timestamp of when entry was created
created_at = DateTimeField(default=datetime.now)
def save(self, *args, **kwargs):
if not self.created_at:
self.created_at = datetime.now()
self.updated_at = datetime.now()
return super(CreateUpdateDocument, self).save(*args, **kwargs)
Традиционно, я поставил creation_date
по умолчанию datetime.now()
а затем скрыли поле в форме администратора, чтобы удалить возможность перезаписи пользователем правильного значения. Для этого не требуется почти никакого кода.
переопределение метода save, предложенного Willian, также эффективно, поскольку вы можете программно блокировать любые обновления creation_date
обновить modfied_date
в то же время.
вы можете использовать параметр auto_now_add состоянию на документация:
class MyModel(mongoengine.Document):
creation_date = mongo.DateTimeField(auto_now_add = True)
modified_date = mongo.DateTimeField(auto_now = True)