web-dev-qa-db-ja.com

ドキュメントのMongoenginecreation_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()

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

30
josephmisiti

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)
58
Willian

余談ですが、作成時間は_id属性にスタンプされます。

YourObject.id.generation_time

日時スタンプを差し上げます。

21
Ben Hughes
# -*- 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
allisson

優れたソリューションの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)をデータベースに保存することをお勧めします。

4
codebutler

多数のドキュメントでタイムスタンプフィールドを使用している場合は、代わりに抽象的なドキュメントを作成することで、コードを保持できます [〜#〜] 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)
3
Vikas Gulati

私の推奨する解決策は、@propertyデコレータを使用して、ObjectIdから抽出された作成日時を返すことです。

@property
def creation_stamp(self):
    return self.id.generation_time
3
Emanuel Ey

従来、私は_creation_date_のデフォルトをdatetime.now()に設定してから、管理フォームのフィールドを非表示にして、ユーザーが正しい値を上書きする可能性を排除していました。それはほとんどコードを必要としません。

_creation_date_の更新をプログラムでブロックし、同時に_modfied_date_を更新できるため、Willianによって提案されたsaveメソッドをオーバーライドすることも効果的です。

0
Darrell Hawley