|
30 | 30 | clear_events = Signal() |
31 | 31 |
|
32 | 32 |
|
33 | | -def is_same_object(instance, webhook_data, request_id): |
| 33 | +def last_matching_index(instance, queue, request_id): |
34 | 34 | """ |
35 | | - Compare the given instance to the most recent queued webhook object, returning True |
36 | | - if they match. This check is used to avoid creating duplicate webhook entries. |
| 35 | + Find the latest queued webhook object matching the given instance, returning its index. |
| 36 | + If no object is found, return None. This check is used to avoid creating duplicate webhook |
| 37 | + entries. |
37 | 38 | """ |
38 | | - return ( |
39 | | - ContentType.objects.get_for_model(instance) == webhook_data['content_type'] and |
40 | | - instance.pk == webhook_data['object_id'] and |
41 | | - request_id == webhook_data['request_id'] |
42 | | - ) |
| 39 | + try: |
| 40 | + return max( |
| 41 | + index_ for index_, webhook_data in enumerate(queue) |
| 42 | + if ContentType.objects.get_for_model(instance) == webhook_data['content_type'] and |
| 43 | + instance.pk == webhook_data['object_id'] and |
| 44 | + request_id == webhook_data['request_id'] |
| 45 | + ) |
| 46 | + except ValueError: |
| 47 | + return None |
43 | 48 |
|
44 | 49 |
|
45 | 50 | @receiver((post_save, m2m_changed)) |
@@ -89,10 +94,10 @@ def handle_changed_object(sender, instance, **kwargs): |
89 | 94 |
|
90 | 95 | # If this is an M2M change, update the previously queued webhook (from post_save) |
91 | 96 | queue = events_queue.get() |
92 | | - if m2m_changed and queue and is_same_object(instance, queue[-1], request.id): |
| 97 | + if m2m_changed and queue and (last_index := last_matching_index(instance, queue, request.id)) is not None: |
93 | 98 | instance.refresh_from_db() # Ensure that we're working with fresh M2M assignments |
94 | | - queue[-1]['data'] = serialize_for_event(instance) |
95 | | - queue[-1]['snapshots']['postchange'] = get_snapshots(instance, action)['postchange'] |
| 99 | + queue[last_index]['data'] = serialize_for_event(instance) |
| 100 | + queue[last_index]['snapshots']['postchange'] = get_snapshots(instance, action)['postchange'] |
96 | 101 | else: |
97 | 102 | enqueue_object(queue, instance, request.user, request.id, action) |
98 | 103 | events_queue.set(queue) |
|
0 commit comments