Mongoengine creation_time атрибут в документе
Я пытаюсь добавить creation_time
приписать мои документы. Следующее будет примером:
import datetime
class MyModel(mongoengine.Document):
creation_date = mongo.DateTimeField()
modified_date = mongo.DateTimeField(default=datetime.datetime.now)
Модели Django имеют встроенный параметр для их DateTimeField
такие объекты, как add_now
и т. д., но MongoEngine не поддерживает это.
Мне интересно, если лучший способ сделать это заключается в следующем:
m,created = MyModel.objects.get_or_create()
if created:
m.creation_date = datetime.datetime.now()
или, если есть лучший, более хороший способ.
8 ответов
Вы можете переопределить метод сохранения.
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)
Кроме того, время создания отпечатано в _id
атрибут - если вы делаете:
YourObject.id.generation_time
Даст вам штамп даты и времени.
Хорошим решением является повторное использование единого обработчика сигналов для нескольких документов.
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
) в вашей базе данных.
Если вы используете поле метки времени в пачке документов, вы можете сохранить свой код СУХИМ, создав вместо этого абстрактный документ.
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)
Мое предпочтительное решение состоит в том, чтобы использовать @property
декоратор возвращает дату и время создания, извлеченную из ObjectId:
@property
def creation_stamp(self):
return self.id.generation_time
# -*- 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)
Попробуйте использовать значение лямбда:
import datetime
from mongoengine import Document
class MyModel(Document):
creation_date = mongo.DateTimeField()
modified_date = mongo.DateTimeField(default=lambda : datetime.datetime.now())
Традиционно я установил creation_date
по умолчанию datetime.now()
а затем скрыли поле в форме администратора, чтобы исключить возможность перезаписи пользователем правильного значения. Это почти не требует кода.
Переопределение метода сохранения, предложенного Виллианом, также эффективно, поскольку вы можете программно блокировать любые обновления 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)