web-dev-qa-db-ja.com

djangoでいつpre_save、save、post_saveを使用するのですか?

pre_save, save, post_saveをオーバーライドまたは定義して、モデルインスタンスが保存されたときに必要な処理を実行できることがわかりました。

どの状況でどの方法が推奨されますか?その理由は?

27
eugene

例を挙げて説明します。

pre_save および post_save は、モデルによって送信される signals です。簡単に言うと、モデルのsaveの前または後に実行するアクションが呼び出されます。

A save次のステップをトリガーします

  • 保存前の信号を発信します。
  • データを前処理します。
  • ほとんどのフィールドは前処理を行わず、フィールドデータはそのまま保持されます。
  • データベースのデータを準備します。
  • データベースにデータを挿入します。
  • 保存後の信号を発信します。

Djangoはこれらのシグナルをオーバーライドする方法を提供します。

さて、

pre_save信号は、データベースへの実際の保存が行われる前に、いくつかの処理でオーバーライドできます-例:(pre_saveが頭のてっぺんで理想的な場所の良い例がわかりません)

notがまだ編集されているModelAのすべてのオブジェクトへの参照を格納するModelBがあるとします。このため、ModelAModelBメソッドが呼び出される直前にpre_saveシグナルを登録してsaveに通知することができます(post_saveの登録を妨げるものはありません信号もここにあります)。

これで、モデルのsaveメソッド(シグナルではない)が呼び出されます-デフォルトでは、すべてのモデルにsaveメソッドがありますが、オーバーライドできます。

class ModelB(models.Model):
    def save(self):
        #do some custom processing here: Example: convert Image resolution to a normalized value
        super(ModelB, self).save()

次に、post_save信号を登録できます(これはpre_saveより使用されます)

一般的なユースケースは、UserProfileオブジェクトがシステムで作成されるときのUserオブジェクトの作成です。

システム内のすべてのUserProfileに対応するUserオブジェクトを作成するpost_save信号を登録できます。

シグナルは、物事をモジュール化し、明示的に保つ方法です。 (明示的にModelAに通知しますsaveまたはModelBで何かを変更した場合)

この質問にもっとよく答えるために、より具体的な現実の例を考えます。その間、私はこれがあなたに役立つことを願っています

26
karthikr
pre_save

トランザクションが保存される前に使用されます。

post_save

トランザクションの保存後に使用されます。

たとえば、FileFieldまたはImageFieldがあり、fileまたはimageが実際に存在するかどうかを確認する場合は、pre_saveを使用できます。

UserProfileがあり、新しいUserが作成された瞬間に新しいものを作成したい場合は、post_saveを使用できます。

再帰のリスクを忘れないでください。 .updateメソッドの代わりにpost_saveメソッドをinstance.save()呼び出しで使用する場合は、post_saveシグナルを切断する必要があります。

Signal.disconnect(receiver = None、sender = None、dispatch_uid = None)[source]シグナルからレシーバーを切断するには、Signal.disconnect()を呼び出します。引数はSignal.connect()で説明されています。このメソッドは、レシーバーが切断されている場合はTrueを、切断されていない場合はFalseを返します。

Receiver引数は、切断する登録済みのレシーバーを示します。 dispatch_uidを使用して受信者を識別する場合は、Noneになることがあります。

...その後、再度接続します。

pdate()メソッドはpre_およびpost_シグナルを送信しません。

2
SlowSuperman