소스 검색

21390 skip m2m processing for internal models to avoid extraneous ObjectChange records

Arthur 2 일 전
부모
커밋
de812a5a85
1개의 변경된 파일22개의 추가작업 그리고 16개의 파일을 삭제
  1. 22 16
      netbox/core/signals.py

+ 22 - 16
netbox/core/signals.py

@@ -209,22 +209,28 @@ def handle_deleted_object(sender, instance, **kwargs):
     # for the forward direction of the relationship, ensuring that the change is recorded.
     # Similarly, for many-to-one relationships, we set the value on the related object to None
     # and save it to trigger a change record on that object.
-    for relation in instance._meta.related_objects:
-        if type(relation) not in [ManyToManyRel, ManyToOneRel]:
-            continue
-        related_model = relation.related_model
-        related_field_name = relation.remote_field.name
-        if not issubclass(related_model, ChangeLoggingMixin):
-            # We only care about triggering the m2m_changed signal for models which support
-            # change logging
-            continue
-        for obj in related_model.objects.filter(**{related_field_name: instance.pk}):
-            obj.snapshot()  # Ensure the change record includes the "before" state
-            if type(relation) is ManyToManyRel:
-                getattr(obj, related_field_name).remove(instance)
-            elif type(relation) is ManyToOneRel and relation.null and relation.on_delete not in (CASCADE, RESTRICT):
-                setattr(obj, related_field_name, None)
-                obj.save()
+    #
+    # Skip this for private models (e.g. CablePath) whose lifecycle is an internal
+    # implementation detail. Django's on_delete handlers (e.g. SET_NULL) already take
+    # care of the database integrity; recording changelog entries for the related
+    # objects would be spurious. (Ref: #21390)
+    if not getattr(instance, '_netbox_private', False):
+        for relation in instance._meta.related_objects:
+            if type(relation) not in [ManyToManyRel, ManyToOneRel]:
+                continue
+            related_model = relation.related_model
+            related_field_name = relation.remote_field.name
+            if not issubclass(related_model, ChangeLoggingMixin):
+                # We only care about triggering the m2m_changed signal for models which support
+                # change logging
+                continue
+            for obj in related_model.objects.filter(**{related_field_name: instance.pk}):
+                obj.snapshot()  # Ensure the change record includes the "before" state
+                if type(relation) is ManyToManyRel:
+                    getattr(obj, related_field_name).remove(instance)
+                elif type(relation) is ManyToOneRel and relation.null and relation.on_delete not in (CASCADE, RESTRICT):
+                    setattr(obj, related_field_name, None)
+                    obj.save()
 
     # Enqueue the object for event processing
     queue = events_queue.get()