5

モデル用にいくつかのスマートな汎用カウンターとマネージャーを作成しました (select countクエリなどを避けるため)。したがって、私は post_save のためにいくつかの重いロジックを実行しています。

必要がないときにシグナルを処理しないようにしたいと思います。完璧なインターフェースは次のようになると思います:

instance.save(dispatch_signal=False)

どうすればこれを達成できますか?


アップデート

誰かが興味を持っている場合は、私が何をしているのかについての詳細情報:

  1. 汎用カウンターは別のテーブルに格納されます
  2. Django がオブジェクト リストを改ページするたびに、カスタム マネージャーのオーバーライドされた count() メソッドを呼び出します。これは基本的に、適切なオブジェクト クラスの静的カウンター値を取得します。
  3. 信号は、カウンター更新のロジックをトリガーします。これは、関連するモデルの多くの側面をチェックするため、少し複雑です (つまり、ネストされたカテゴリ ツリーに基づいて可視性プロパティを生成する必要があります)。1 つのカウンターが多くの異なるモデルに依存しているため、このロジックを Model.save() に入れることはできません。そのロジックをバラバラにばらばらにするのではなく、ひとつにまとめたいと思っています。
  4. モデルの一部を非正規化しているため、テーブル全体で特定の値を書き換え (複製) しています。
  5. テスト目的で、小さなコマンド拡張 ( Dilla ) を実行して、ランダムなデータを設定します。
  6. 不要なシグナルがトリガーされていることに気付いたので、条件付きで実行したいと思います。

それが十分に明確であることを願っています。言葉の間違いをお許しください。

4

4 に答える 4

15

信号を切断して再接続できます。with:このユーティリティ クラスでステートメントを使用してみてください。

class SignalBlocker(object):
    def __init__(self, signal, receiver, **kwargs):
        self.signal = signal
        self.receiver = receiver
        self.kwargs = kwargs

    def __enter__(self, *args, **kwargs):
        self.signal.disconnect(self.receiver)

    def __exit__(self, *args, **kwargs):
        self.signal.connect(self.receiver, **self.kwargs)

以下を使用できるようになりました。

with SignalBlocker(post_save, my_post_save_handler):
    instance.save()
于 2012-06-04T12:49:48.970 に答える
14

迅速で汚い解決策は次のとおりです。

from django.db.models.signals import post_save
from somewhere_in_my_app import my_post_save_handler

post_save.disconnect(my_post_save_handler)
instance.save()
post_save.connect(my_post_save_handler)

ただし、それ以外の場合は、ロジックをsave()モデルのメソッドに移動することを強くお勧めします.

于 2009-02-23T12:05:29.197 に答える
2

またはシグナルハンドラで引数を呼び出しinstance.save_base(raw=True)て確認することもできます。rawpre_savepost_save

def my_post_save_handler(instance, raw, **kwargs):
    if not raw:
        heavy_logic()

砂糖を加えて、完璧なインターフェースを得ることができます。

class MyModel:
    def save(self, dispatch_signal=True, **kwargs):
        self.save_base(raw=not dispatch_signal, **kwargs)

save_base()これはDjangoのパブリックAPIの一部ではないため、将来のバージョンで変更される可能性があることに注意してください。

于 2009-09-14T10:39:02.690 に答える