"""Allows you to create generic receivers for django's signal system Why do you need generic recievers you ask? Say you need want to record when a group of Models are saved and you want to record their publish date, but they have different field names def record_pubdate(instance=instance, signal=None, sender=None, date_field=None): ip = ItemPublish(object_id=instance.id, pub_date=getattr(instance, date_field) ip.save() receivers = [] for Model, date_field in ( (blog.Entry, 'pub_date', (bookmarks.Bookmark, 'timestamp'), (rss.Entry, 'update_date') ): receivers.append(generic_receiver(record_pubdate, date_field=date_field) dispatcher.connect(receivers[-1], signal=post_save, sender=Model) """ def generic_receiver(callable, *extra_args, **extra_kwargs): def inner(*args, **kwargs): args = args + extra_args kwargs.update(extra_kwargs) callable(*args, **kwargs) return inner def test_kwarg_generic_receiver(): from django.dispatch import dispatcher # This is needed to keep our anonymous functions alive # This is needed because the signals system removes the relationship # if the function looses scope scope = [] def my_kwarg_receiver(signal=None, sender=None, date_field=None): result_list.append(date_field) test_signal = object() # Test the kwarg receiver time_field_list = ['time', 'pub_date'] result_list = [] for date_field in time_field_list: scope.append(generic_receiver(my_kwarg_receiver, date_field=date_field)) dispatcher.connect(scope[-1], signal=test_signal) dispatcher.send(test_signal) assert result_list == ['time', 'pub_date'] def test_arg_generic_receiver(): from django.dispatch import dispatcher # This is needed to keep our anonymous functions alive # This is needed because the signals system removes the relationship # if the function looses scope scope = [] def my_kwarg_receiver(date_field, signal=None, sender=None): result_list.append(date_field) test_signal = object() # Test the kwarg receiver time_field_list = ['time', 'pub_date'] result_list = [] for date_field in time_field_list: scope.append(generic_receiver(my_kwarg_receiver, date_field)) dispatcher.connect(scope[-1], signal=test_signal) dispatcher.send(test_signal) assert result_list == ['time', 'pub_date'] def test_arg_kwarg_generic_receiver(): from django.dispatch import dispatcher # This is needed to keep our anonymous functions alive # This is needed because the signals system removes the relationship # if the function looses scope scope = [] result_list = [] def my_kwarg_receiver(date_field, signal=None, sender=None, other_field=None): result_list.append( (date_field, other_field) ) test_signal = object() # Test the kwarg receiver field_list = [('time', 1), ('pub_date', 2)] for date_field, other_field in field_list: scope.append(generic_receiver(my_kwarg_receiver, date_field, other_field=other_field)) dispatcher.connect(scope[-1], signal=test_signal) dispatcher.send(test_signal) assert result_list == field_list if __name__ == '__main__': test_arg_generic_receiver() test_kwarg_generic_receiver() test_arg_kwarg_generic_receiver()