44from unittest import skip
55
66from django .contrib .contenttypes .models import ContentType
7+ from django .db import connection
78from django .test import override_settings
9+ from django .test .utils import CaptureQueriesContext
810from django .urls import reverse
911from nautobot .apps .testing import ViewTestCases
1012from nautobot .core .testing .utils import disable_warnings
1315
1416from nautobot_ssot .choices import SyncLogEntryActionChoices , SyncLogEntryStatusChoices
1517from nautobot_ssot .models import Sync , SyncLogEntry
18+ from nautobot_ssot .views import SyncLogEntryUIViewSet
1619
1720
1821class SyncViewsTestCase ( # pylint: disable=too-many-ancestors
@@ -150,7 +153,7 @@ def setUpTestData(cls):
150153 target = "Nautobot" ,
151154 start_time = datetime .now (),
152155 dry_run = False ,
153- diff = {},
156+ diff = {"foo" : "bar" },
154157 job_result = job_result ,
155158 )
156159
@@ -169,3 +172,45 @@ def setUpTestData(cls):
169172 @skip ("Not implemented" )
170173 def test_list_objects_with_constrained_permission (self ):
171174 pass
175+
176+ def test_queryset_optimization (self ):
177+ """Test that the SyncLogEntry queryset uses select_related and only() correctly."""
178+ # Get the queryset from the viewset
179+ queryset = SyncLogEntryUIViewSet .queryset
180+
181+ # Evaluate the queryset to get all log entries
182+ # This should trigger a single query with select_related
183+ with CaptureQueriesContext (connection ) as ctx :
184+ log_entries = list (queryset .all ())
185+
186+ # Should have exactly 1 query (the main query with select_related)
187+ self .assertEqual (len (ctx .captured_queries ), 1 , "Queryset should use select_related to fetch in one query" )
188+
189+ # Verify we have log entries
190+ self .assertGreater (len (log_entries ), 0 )
191+
192+ # Test that accessing sync-related fields doesn't trigger additional queries
193+ with CaptureQueriesContext (connection ) as ctx :
194+ for entry in log_entries :
195+ # Access all the sync fields that are specified in the only() clause
196+ _ = entry .sync .id
197+ _ = entry .sync .source
198+ _ = entry .sync .target
199+ _ = entry .sync .start_time
200+ # Also test accessing the sync object itself (for __str__)
201+ _ = str (entry .sync )
202+
203+ # Should have 0 additional queries since select_related was used
204+ self .assertEqual (len (ctx .captured_queries ), 0 , "Accessing sync fields should not trigger additional queries" )
205+
206+ # Verify that sync.diff was NOT loaded (it's not in the only() clause)
207+ # Accessing it should trigger an additional query
208+ with CaptureQueriesContext (connection ) as ctx :
209+ _ = log_entries [0 ].sync .diff
210+
211+ # Should have 1 additional query to fetch the deferred diff field
212+ self .assertEqual (
213+ len (ctx .captured_queries ),
214+ 1 ,
215+ "Accessing sync.diff should trigger an additional query since it wasn't loaded in the original queryset" ,
216+ )
0 commit comments