3

post_save、delete、initシグナルを処理してモデルとそのCRUD操作を追跡し、処理されたこの操作に関するエントリをデータベースに保存したいと思いました。

def handle_model_saved(sender, **kwargs):
  """Trap the signal and do whatever is needed"""
  entry=CRUD_Storage()
  entry.entry='Object \"'+sender._meta.module_name+'\" was saved.'
  entry.save()

次に面白いのは、保存の再帰です...

モデルCRUD_Storageを作成しましたが、pre(post)init、delete、saveなどのシグナルを送信しないようにします。

4

2 に答える 2

3

Djangoがこれらのシグナルを送信するのを防ぐことはできないと思います。

CRUD_Storageただし、モデルの保存をログに記録しないようにハンドラーを調整できます。

def handle_model_saved(sender, **kwargs):
    """Trap the signal and do whatever is needed"""
    if sender == CRUD_Storage:
        # return early to prevent recursion of saves
        return
    entry=CRUD_Storage()
    entry.entry='Object \"'+sender._meta.module_name+'\" was saved.'
    entry.save()
于 2012-01-07T14:50:17.803 に答える
1

これが信号を却下するDRYの方法です。

再帰を回避するためにシグナルを閉じたい場合、簡単な方法は、現在のインスタンスに属性を設定して、次のシグナルが発生しないようにすることです。

これは、指定されたインスタンスに「skip_signal」属性があるかどうかをチェックする単純なデコレータを使用して実行できます。ある場合は、メソッドが呼び出されないようにします。

from functools import wraps

def skip_signal():
    def _skip_signal(signal_func):
        @wraps(signal_func)
        def _decorator(sender, instance, **kwargs):
            if hasattr(instance, 'skip_signal'):
                return None
            return signal_func(sender, instance, **kwargs)  
        return _decorator
    return _skip_signal

これで、次のように使用できます。

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=MyModel)
@skip_signal()
def my_model_post_save(sender, instance, **kwargs):
    # you processing
    pass

m = MyModel()
# Here we flag the instance with 'skip_signal'
# and my_model_post_save won't be called
# thanks to our decorator, avoiding any signal recursion
m.skip_signal  = True
m.save()

お役に立てれば。

于 2014-11-27T23:14:48.520 に答える