我正在尝试在文档中添加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()
或者是否有更好,更好的方式。
答案 0 :(得分:55)
您可以覆盖保存方法。
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)
答案 1 :(得分:21)
顺便说一句,创建时间标记在_id
属性中 - 如果你这样做:
YourObject.id.generation_time
会给你一张日期时间戳。
答案 2 :(得分:4)
# -*- 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)
答案 3 :(得分:4)
一个不错的解决方案是为多个文档重用单个信号处理程序。
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
)总是更好。
答案 4 :(得分:3)
如果您在一堆文档中使用时间戳字段,则可以通过创建抽象文档来保留代码DRY。
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)
答案 5 :(得分:3)
我首选的解决方案是使用@property
装饰器返回从ObjectId中提取的创建日期时间:
@property
def creation_stamp(self):
return self.id.generation_time
答案 6 :(得分:1)
尝试使用lambda值:
import datetime
from mongoengine import Document
class MyModel(Document):
creation_date = mongo.DateTimeField()
modified_date = mongo.DateTimeField(default=lambda : datetime.datetime.now())
答案 7 :(得分:0)
传统上,我已将creation_date
默认设置为datetime.now()
,然后将该字段隐藏在管理表单中,以便您删除用户覆盖正确值的可能性。这几乎不需要代码。
按照Willian的建议覆盖保存方法也很有效,因为您可以编程阻止对creation_date
的任何更新并同时更新modfied_date
。
答案 8 :(得分:-7)
您可以按照documentation使用auto_now_add参数:
class MyModel(mongoengine.Document):
creation_date = mongo.DateTimeField(auto_now_add = True)
modified_date = mongo.DateTimeField(auto_now = True)