diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index d6f08e768..d600667d7 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1,6 +1,5 @@ import django_filters from django.contrib.auth import get_user_model -from django.db.models import Q from django.utils.translation import gettext as _ from extras.filtersets import LocalConfigContextFilterSet @@ -1819,10 +1818,16 @@ class CableFilterSet(TenancyFilterSet, NetBoxModelFilterSet): def _unterminated(self, queryset, name, value): if value: - terminated_ids = queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A).filter(terminations__cable_end=CableEndChoices.SIDE_B).values("id") + terminated_ids = ( + queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A) + .filter(terminations__cable_end=CableEndChoices.SIDE_B) + .values("id") + ) return queryset.exclude(id__in=terminated_ids) else: - return queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A).filter(terminations__cable_end=CableEndChoices.SIDE_B) + return queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A).filter( + terminations__cable_end=CableEndChoices.SIDE_B + ) class CableTerminationFilterSet(BaseFilterSet): diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 3ba5ebd63..d0d321187 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -908,9 +908,9 @@ class VirtualChassisFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): class CableFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): model = Cable fieldsets = ( - (None, ('q', 'filter_id', 'unterminated', 'tag')), + (None, ('q', 'filter_id', 'tag')), (_('Location'), ('site_id', 'location_id', 'rack_id', 'device_id')), - (_('Attributes'), ('type', 'status', 'color', 'length', 'length_unit')), + (_('Attributes'), ('type', 'status', 'color', 'length', 'length_unit', 'unterminated')), (_('Tenant'), ('tenant_group_id', 'tenant_id')), ) region_id = DynamicModelMultipleChoiceField( diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index aed4843e9..1f3b557b5 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -4290,7 +4290,9 @@ class CableTestCase(TestCase, ChangeLoggedFilterSetTests): Cable(a_terminations=[interfaces[9]], b_terminations=[interfaces[10]], label='Cable 5', type=CableTypeChoices.TYPE_CAT6, tenant=tenants[2], status=LinkStatusChoices.STATUS_PLANNED, color='e91e63', length=10, length_unit=CableLengthUnitChoices.UNIT_METER).save() Cable(a_terminations=[interfaces[11]], b_terminations=[interfaces[0]], label='Cable 6', type=CableTypeChoices.TYPE_CAT6, tenant=tenants[2], status=LinkStatusChoices.STATUS_PLANNED, color='e91e63', length=20, length_unit=CableLengthUnitChoices.UNIT_METER).save() Cable(a_terminations=[console_port], b_terminations=[console_server_port], label='Cable 7').save() - Cable(a_terminations=[interfaces[12]], label='Cable 8', type=CableTypeChoices.TYPE_CAT6, tenant=tenants[2], status=LinkStatusChoices.STATUS_DECOMMISSIONING, color='e91e63', length=20, length_unit=CableLengthUnitChoices.UNIT_METER).save() + + # Cable for unterminated test + Cable(a_terminations=[interfaces[12]], label='Cable 8', type=CableTypeChoices.TYPE_CAT6, status=LinkStatusChoices.STATUS_DECOMMISSIONING).save() def test_label(self): params = {'label': ['Cable 1', 'Cable 2']} @@ -4298,7 +4300,7 @@ class CableTestCase(TestCase, ChangeLoggedFilterSetTests): def test_length(self): params = {'length': [10, 20]} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) def test_length_unit(self): params = {'length_unit': CableLengthUnitChoices.UNIT_FOOT}