2013-07-06 25 views
24

Vì vậy, tôi đọc mã nguồn Django (gửi 1.5) rằng bây giờ bạn có thể đăng ký nhiều nhiều tín hiệu đến một chức năng nhận:Củng cố nhiều tín hiệu post_save với một máy thu

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... 

Tuy nhiên, tôi muốn đăng ký nhiều tín hiệu post_save từ các người gửi khác nhau đến cùng một chức năng. Ngay bây giờ, tôi chỉ cần gọi

post_save.connect(fn_name, model_name) 

cho mỗi kiểu máy tôi có. Có cách nào tốt hơn để làm điều này với khả năng trang trí Django 1.5 @receiver mới?

Trả lời

89

Bạn có thể sử dụng mà sử dụng @receiver trang trí:

@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

Đây phải là câu trả lời được chấp nhận, mặc dù nó có thể được làm khô hơn với một trang trí tùy chỉnh. – DylanYoung

+4

Nó có thể được nhiều hơn nữa; tuy nhiên, tôi nghĩ điều đó sẽ gây tổn hại cho sự rõ ràng trong trường hợp này. – freethebees

+0

Câu trả lời hay nhất cho câu hỏi –

18

Bạn có thể bỏ qua model_name và bạn sẽ kết nối với tất cả các mô hình post_save. Sau đó, bạn có thể lọc nếu bạn đang ở trong mô hình phù hợp trong xử lý:

post_save.connect(foo) 

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

hoặc bạn có thể lọc dựa trên lĩnh vực trong mô hình:

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

mỗi sự Django documentation on receivers, thu theo mặc định không cần phải được kết nối với một người gửi cụ thể. Vì vậy, những gì bạn mô tả là chức năng Django mặc định.

Nói cách khác, để thực hiện việc này bằng cách sử dụng trang trí @receiver bạn chỉ cần không chỉ định người gửi trong trình trang trí. Ví dụ:

@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 ... 

này giả định mô hình trông giống như:

class Rebel(models.Model): 
    ... 

class Stormtrooper(models.Model): 
    ... 

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

sẽ không nhận này cũng được gọi vào * mỗi * post_save của mô hình khác? có thể có rất nhiều cuộc gọi ... – nivcaner

+0

@nivcaner vâng, đó là câu hỏi được yêu cầu: sử dụng một 'post_save' để nghe các thay đổi trên nhiều mô hình –

+2

@TylerHayes nhiều mô hình không giống với tất cả các kiểu – DylanYoung

Các vấn đề liên quan