From e81ccb9be693d0c0667e71e93a3d44f0e42a8088 Mon Sep 17 00:00:00 2001 From: Aditya Sharma <100428589+adionit7@users.noreply.github.com> Date: Thu, 22 Jan 2026 04:08:27 +0530 Subject: [PATCH] Fixes #21214: Clean up AutoSyncRecord when detaching from DataSource (#21219) Co-authored-by: adionit7 --- netbox/extras/tests/test_models.py | 52 +++++++++++++++++++++++++++++- netbox/netbox/models/features.py | 2 -- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/netbox/extras/tests/test_models.py b/netbox/extras/tests/test_models.py index 7b2e58646..3156e7a1b 100644 --- a/netbox/extras/tests/test_models.py +++ b/netbox/extras/tests/test_models.py @@ -6,7 +6,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.forms import ValidationError from django.test import tag, TestCase -from core.models import DataSource, ObjectType +from core.models import AutoSyncRecord, DataSource, ObjectType from dcim.models import Device, DeviceRole, DeviceType, Location, Manufacturer, Platform, Region, Site, SiteGroup from extras.models import ConfigContext, ConfigContextProfile, ConfigTemplate, ImageAttachment, Tag, TaggedItem from tenancy.models import Tenant, TenantGroup @@ -754,3 +754,53 @@ class ConfigTemplateTest(TestCase): @tag('regression') def test_config_template_with_data_source_nested_templates(self): self.assertEqual(self.BASE_TEMPLATE, self.main_config_template.render({})) + + @tag('regression') + def test_autosyncrecord_cleanup_on_detach(self): + """Test that AutoSyncRecord is deleted when detaching from DataSource.""" + with tempfile.TemporaryDirectory() as temp_dir: + templates_dir = Path(temp_dir) / "templates" + templates_dir.mkdir(parents=True, exist_ok=True) + + self._create_template_file(templates_dir, 'test.j2', 'Test content') + + data_source = DataSource( + name="Test DataSource for Detach", + type="local", + source_url=str(templates_dir), + ) + data_source.save() + data_source.sync() + + data_file = data_source.datafiles.filter(path__endswith='test.j2').first() + + # Create a ConfigTemplate with data_file and auto_sync_enabled + config_template = ConfigTemplate( + name="TestTemplateForDetach", + data_file=data_file, + auto_sync_enabled=True + ) + config_template.clean() + config_template.save() + + # Verify AutoSyncRecord was created + object_type = ObjectType.objects.get_for_model(ConfigTemplate) + autosync_records = AutoSyncRecord.objects.filter( + object_type=object_type, + object_id=config_template.pk + ) + self.assertEqual(autosync_records.count(), 1, "AutoSyncRecord should be created") + + # Detach from DataSource + config_template.data_file = None + config_template.data_source = None + config_template.auto_sync_enabled = False + config_template.clean() + config_template.save() + + # Verify AutoSyncRecord was deleted + autosync_records = AutoSyncRecord.objects.filter( + object_type=object_type, + object_id=config_template.pk + ) + self.assertEqual(autosync_records.count(), 0, "AutoSyncRecord should be deleted after detaching") diff --git a/netbox/netbox/models/features.py b/netbox/netbox/models/features.py index 653dc50c8..b6eb62884 100644 --- a/netbox/netbox/models/features.py +++ b/netbox/netbox/models/features.py @@ -569,7 +569,6 @@ class SyncedDataMixin(models.Model): ) else: AutoSyncRecord.objects.filter( - datafile=self.data_file, object_type=object_type, object_id=self.pk ).delete() @@ -582,7 +581,6 @@ class SyncedDataMixin(models.Model): # Delete AutoSyncRecord object_type = ObjectType.objects.get_for_model(self) AutoSyncRecord.objects.filter( - datafile=self.data_file, object_type=object_type, object_id=self.pk ).delete()