2011-11-11 12 views
22

私の文書にcreation_time属性を追加しようとしています。次は、例のようになります。文書のMongoengine 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() 

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

答えて

48

保存メソッドをオーバーライドできます。

class MyModel(mongoengine.Document): 
    creation_date = mongo.DateTimeField(auto_now_add = True) 
    modified_date = mongo.DateTimeField(auto_now = True) 
+0

これは私がまさに必要です。私はデフォルトのビットを見つけましたが、変更された時間を追跡するsaveメソッドをオーバーライドするのは完璧です。ありがとうございました:) – Dawson

+0

これの問題は、aの代わりに更新を行うと保存関数が呼び出されないということです。セーブ権? – Nazariy1995

+0

@ Brenden1995いいえ、更新では動作しません。 – Willian

-7

ユーザーが正しい値を上書きするそれはほとんどコードを必要としません。

また、creation_dateのアップデートをプログラマチックにブロックしてmodfied_dateを同時に更新することができるため、ウィリアンの提案通りにセーブメソッドをオーバーライドすることも有効です。

+0

これらのパラメータはmengoengineでは機能しません – josephmisiti

+1

これはもっとも不幸です。次に、受け入れられた回答のように保存を上書きすることが正しい答えです。私は、しかし、機能を追加するパッチを作成するだろう:) –

+0

これはDjangoのお嬢さんではありません... –

0

伝統的に、私はdatetime.now()creation_dateデフォルトを設定して、その後、あなたがの可能性を取り除くので、管理フォーム上のフィールドを隠して:あなたはdocumentationごとにパラメータをauto_now_add使用することができ

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

「伝統的に」と言えば、特にDjango ORMやMongoEngineを使用することを意味しますか? – josephmisiti

18

はさておき、作成時間は_id属性に刻印されて - あなたが行う場合:

YourObject.id.generation_time 

はあなたの日時スタンプを与えるだろう。

+0

まさに私が探していたもの、ありがとう。 –

+2

これは受け入れられた回答よりも優れています。 'created_time(self):return self.id.generation_time if self.id else None' – aaaronic

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

単一のシグナルハンドラを複数のドキュメントに再利用していることをお勧めします。

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.nowの代わりにdatetime.utcnow)を格納することも常に良い方法です。

1

複数のドキュメントでタイムスタンプフィールドを使用している場合は、代わりに抽象ドキュメントを作成してコード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

あなたは' self.updated_at = datetimeを入れたいかもしれません。 .now() 'を' else'文の下に置くことで、 "updated_atがnoneであればモデルが更新されていないことを意味する"という考え方を保つことができます。 – ldavid

3

私の好適な解決策がのObjectIdから抽出されたとして、作成日時を返すように@propertyデコレータを使用することです:

@property 
def creation_stamp(self): 
    return self.id.generation_time 
関連する問題