Fixes #22812: Don't show a spurious "0 jobs" row for jobless objects
Django's Collector calls into the jobs GenericRelation branch unconditionally, so ConfirmCollector recorded a zero count for objects with no jobs. _get_dependent_objects then added a CountOnly(0), and the delete-confirmation page rendered "The following objects will be deleted as a result of this action." plus a "0 jobs" row for every jobless JobsMixin object. Only record a count when there are actually jobs.
This commit is contained in:
parent
f2923f4ce4
commit
be69c55a99
|
|
@ -199,6 +199,16 @@ class ConfirmCollectorTestCase(TestCase):
|
|||
self.assertEqual(list(wrapper), [])
|
||||
self.assertTrue(wrapper.count_only)
|
||||
|
||||
def test_confirm_collector_omits_jobs_when_none(self):
|
||||
# A jobless object must not record a zero count, or the confirmation page would show a
|
||||
# spurious "0 jobs" row (#22812 regression).
|
||||
datasource = DataSource.objects.create(name='DS', type='local', source_url='/tmp/test')
|
||||
|
||||
collector = ConfirmCollector(using=router.db_for_write(DataSource))
|
||||
collector.collect([datasource])
|
||||
|
||||
self.assertNotIn(Job, collector.generic_relation_counts)
|
||||
|
||||
|
||||
class ObjectDeleteViewCountsTestCase(ViewTestCase):
|
||||
"""
|
||||
|
|
@ -258,3 +268,18 @@ class ObjectDeleteViewCountsTestCase(ViewTestCase):
|
|||
self.assertIsInstance(dependent_objects[Job], CountOnly)
|
||||
self.assertEqual(len(dependent_objects[Job]), 50)
|
||||
self.assertTrue(dependent_objects[Job].count_only)
|
||||
|
||||
def test_get_dependent_objects_omits_jobs_when_none(self):
|
||||
from netbox.views.generic.object_views import ObjectDeleteView
|
||||
|
||||
# A module with no jobs must not produce a CountOnly(0) entry (#22812 regression).
|
||||
module = ScriptModule.objects.create(
|
||||
file_root=ManagedFileRootPathChoices.SCRIPTS,
|
||||
file_path=f'test_{uuid.uuid4().hex[:8]}.py',
|
||||
)
|
||||
|
||||
view = ObjectDeleteView()
|
||||
view.queryset = ScriptModule.objects.all()
|
||||
dependent_objects = view._get_dependent_objects(module)
|
||||
|
||||
self.assertNotIn(Job, dependent_objects)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,12 @@ class ConfirmCollector(Collector):
|
|||
from core.models import Job
|
||||
|
||||
if source is not None and getattr(objs, 'model', None) is Job:
|
||||
self.generic_relation_counts[Job] = self.generic_relation_counts.get(Job, 0) + objs.count()
|
||||
# Django calls this branch for the jobs relation even when there are none; only record
|
||||
# a count when there are actually jobs, so jobless objects don't get a spurious
|
||||
# "0 jobs" row on the delete-confirmation page.
|
||||
count = objs.count()
|
||||
if count:
|
||||
self.generic_relation_counts[Job] = self.generic_relation_counts.get(Job, 0) + count
|
||||
return None
|
||||
return super().collect(objs, source=source, *args, **kwargs)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue