ドキュメントのMongoengine creation_time属性

私は自分のドキュメントに 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()

またはより良い、より良い方法がある場合。

24

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)
51
追加された
save ではなく clean メソッドをオーバーライドするとここのドキュメント
追加された 著者 xialu,
@ Brenden1995いいえ、それは更新で動作しません。
追加された 著者 Willian,
これはまさに私が必要としていたものです。私はデフォルトのビットを見つけましたが、変更された時間を追跡するsaveメソッドをオーバーライドするのは完璧です。ありがとうございました :)
追加された 著者 Dawson,
しかし、この問題は、.save権限の代わりに更新を行うとsave関数が呼び出されないことです。
追加された 著者 Nazariy1995,

脇に、作成時間は _id 属性にスタンプされます。

YourObject.id.generation_time

あなたに日時計を与えるでしょう。

18
追加された
これは受け入れられた答えよりも優れています。 @property を次のような関数で使用してcreated_timeを取得しました: def created_at(self):self.id else return
追加された 著者 aaaronic,
正確に私が探していたもの、ありがとう。
追加された 著者 Viktor Stískala,

あなたは、ドキュメント

class MyModel(mongoengine.Document):
    creation_date = mongo.DateTimeField(auto_now_add = True)
    modified_date = mongo.DateTimeField(auto_now = True)
7
追加された
これらのパラメータは、mongoengineでは機能しません
追加された 著者 josephmisiti,
それは最も不幸です。次に、受け入れられた回答のように保存を上書きすることが正しい答えです。私は機能を追加するパッチを作成する:)
追加された 著者 Laur Ivan,
ケアは少し説明する?
追加された 著者 Laur Ivan,
これはDjangoの男じゃない...
追加された 著者 Ron Reiter,

良い解決策の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 には常にアプリが最初に読み込まれたときの時刻に設定されます。

また、データベースに datetime.now の代わりに datetime.utcnow を格納する方が良いでしょう。

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)
4
追加された

私の好みの解決方法は、 @property デコレータを使用して、ObjectIdから抽出した作成日時を返すことです。

@property
def creation_stamp(self):
    return self.id.generation_time
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)
2
追加された
else ステートメントの下に self.updated_at = datetime.now()を置くと、「updated_atがnoneの場合は、モデルは決して更新されませんでした "。
追加された 著者 ldavid,

伝統的に、私は creation_date のデフォルトを datetime.now()に設定し、管理フォームにフィールドを隠しておいて、ユーザが正しい値。それはほとんどコードを必要としません。

creation_date の更新をプログラマチックにブロックして modfied_date を同時に更新できるので、ウィリアンの提案するsaveメソッドをオーバーライドすることも効果的です。

0
追加された
「伝統的に」と言えば、Django ORMやMongoEngineを具体的に使用することを意味しますか?
追加された 著者 josephmisiti,