ドキュメントにcreation_time
属性を追加しようとしています。次に例を示します。
import datetime
class MyModel(mongoengine.Document):
creation_date = mongo.DateTimeField()
modified_date = mongo.DateTimeField(default=datetime.datetime.now)
Djangoモデルには、add_now
などのDateTimeField
オブジェクトのパラメーターが組み込まれていますが、MongoEngineはこれをサポートしていません。
これを行うための最良の方法は次のとおりかどうか疑問に思っています。
m,created = MyModel.objects.get_or_create()
if created:
m.creation_date = datetime.datetime.now()
または、より良い、より良い方法がある場合。
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)
余談ですが、作成時間は_id
属性にスタンプされます。
YourObject.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)
優れたソリューションの1つは、単一のシグナルハンドラーを複数のドキュメントに再利用することです。
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
)をデータベースに保存することをお勧めします。
多数のドキュメントでタイムスタンプフィールドを使用している場合は、代わりに抽象的なドキュメントを作成することで、コードを保持できます [〜#〜] 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)
私の推奨する解決策は、@property
デコレータを使用して、ObjectIdから抽出された作成日時を返すことです。
@property
def creation_stamp(self):
return self.id.generation_time
従来、私は_creation_date
_のデフォルトをdatetime.now()
に設定してから、管理フォームのフィールドを非表示にして、ユーザーが正しい値を上書きする可能性を排除していました。それはほとんどコードを必要としません。
_creation_date
_の更新をプログラムでブロックし、同時に_modfied_date
_を更新できるため、Willianによって提案されたsaveメソッドをオーバーライドすることも効果的です。