fix: use sender for m2m signal dispatch connection

This fix adds support for a use case where a single m2m through model is
used on multiple models. When the reciever is used for the dispatch uid
in this use case it cause duplicated logs because the through model
singal connection happens multiple times.

By changing the m2m signal connection to use the sender for the dispatch
uid this duplication is prevented because the signal connection only
happens once for the through model.

Refs: #685
This commit is contained in:
Christopher Charbonneau Wells 2024-11-10 16:53:52 +00:00
parent d4f99c2729
commit 58885814b1

View file

@ -202,7 +202,7 @@ class AuditlogModelRegistry:
m2m_changed.connect(
receiver,
sender=m2m_model,
dispatch_uid=self._dispatch_uid(m2m_changed, receiver),
dispatch_uid=self._m2m_dispatch_uid(m2m_changed, m2m_model),
)
def _disconnect_signals(self, model):
@ -218,13 +218,17 @@ class AuditlogModelRegistry:
m2m_model = getattr(field, "through")
m2m_changed.disconnect(
sender=m2m_model,
dispatch_uid=self._dispatch_uid(m2m_changed, receiver),
dispatch_uid=self._m2m_dispatch_uid(m2m_changed, m2m_model),
)
del self._m2m_signals[model]
def _dispatch_uid(self, signal, receiver) -> DispatchUID:
"""Generate a dispatch_uid which is unique for a combination of self, signal, and receiver."""
return id(self), id(signal), id(receiver)
def _m2m_dispatch_uid(self, signal, sender) -> DispatchUID:
"""Generate a dispatch_uid which is unique for a combination of self, signal, and sender."""
return id(self), id(signal), id(sender)
def _get_model_classes(self, app_model: str) -> list[ModelBase]:
try: