2013-07-06 13 views
24

で複数のpost_save信号を統合だから私はあなたが今受信機能に複数の複数の信号を登録することができること(1.5ポスト)Djangoのソースコードを読む:は、一つの受信機

def receiver(signal, **kwargs): 
    """ 
    A decorator for connecting receivers to signals. Used by passing in the 
    signal (or list of signals) and keyword arguments to connect:: 

     @receiver(post_save, sender=MyModel) 
     def signal_receiver(sender, **kwargs): 
      ... 

     @receiver([post_save, post_delete], sender=MyModel) 
     def signals_receiver(sender, **kwargs): 
      ... 

    """ 
    ... implementation code... 

はしかし、私は複数のpost_save信号を登録したいです別の送信者から同じ機能に。今は、私が持っているモデルごとに

post_save.connect(fn_name, model_name) 

と呼んでいます。新しいDjango 1.5 @receiverデコレータ機能でこれを行うより良い方法はありますか?

答えて

89

あなたは@receiverデコレータを使用していることを使用することができます。

@receiver(post_save, sender=Model1) 
@receiver(post_save, sender=Model2) 
@receiver(post_save, sender=Model3) 
def my_signal_handle(sender , **kwargs) 
    # some code here 
+1

これは受け入れられる答えですが、カスタムデコレータでより乾燥させることもできます。 – DylanYoung

+4

それはもっと乾燥している可能性があります。しかし、私はこれが明瞭さを失うことになると思います。 – freethebees

+0

質問のベストアンサー –

18

model_nameをスキップして、すべてのモデルpost_saveに接続できます。

post_save.connect(foo) 

def foo(sender, **kwargs): 
    if sender not in [FooModel, BarModel]: 
     return 
    ... actual code ... 

か、モデル内のフィールドに基づいてフィルタリングすることができます:Django documentation on receiversパー

def foo(sender, **kwargs): 
    if not getattr(sender, 'process_by_foo', False): 
     return 
    ... actual code ... 
29

、デフォルトで受信機がする必要はありませんそして、あなたは、ハンドラの右のモデルである場合にフィルタリングすることができます特定の送信者に接続する必要があります。だからあなたが記述しているのは、デフォルトのDjangoの機能です。

つまり、@receiverデコレータを使用するには、単にデコレータに送信者を指定しないでください。たとえば、次のように

@receiver(post_save) # instead of @receiver(post_save, sender=Rebel) 
def set_winner(sender, instance=None, created=False, **kwargs): 
    list_of_models = ('Rebel', 'Stormtrooper', 'Battleground') 
    if sender.__name__ in list_of_models: # this is the dynamic part you want 
     if created: # only run when object is first created 
      ... set the winner ... 

これがどのように見えるのモデルを前提としています

class Rebel(models.Model): 
    ... 

class Stormtrooper(models.Model): 
    ... 

class Battleground(models.Model): 
    ... 
+6

は、この受信機はまた、*すべてのコール得ることはありません*他のモデルのpost_save?それはたくさんの呼び出しになる可能性があります... – nivcaner

+0

@nivcanerはい質問が何を求めているのですか?複数のモデルの変更を聞くために 'post_save'を使用してください –

+2

@TylerHayes複数のモデルはすべてのモデルと同じではありません – DylanYoung

関連する問題