Generic Recievers For Signals

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""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()

More like this

  1. Callable object as signal receiver by diverman 5 years ago
  2. Signal to notify new saved comments by arthurfurlan 4 years, 10 months ago
  3. easy signal registration by aisbaa 2 years, 6 months ago
  4. manually models unique_together check via signals by jedie 4 years, 9 months ago
  5. Show logged users - keeping track of users login and logout by albertorcf 1 year, 7 months ago

Comments

neithere (on May 15, 2009):

Another option is to use weak=False in connect().

#

(Forgotten your password?)