Ver Fonte

Fixes #18585: filtering circuits by location (#18641)

* Fixes #18585: filtering circuits by location

This also fixes a related issue where selected filter is not shown in
the filter form.

Changes:
- Adds `CircuitFilterSet.location_id` field to enable filtering with
  incoming GET params
- Adds `CirciotFilterForm.location_id` field to enable filtering from
  list form
- Adds `location_id` to the Location fieldset on `CircuitFilterForm`

* Adds test for new CircuitFilterset.location_id filter
Jason Novinger há 1 ano atrás
pai
commit
70dddb673b

+ 5 - 0
netbox/circuits/filtersets.py

@@ -234,6 +234,11 @@ class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilte
         to_field_name='slug',
         to_field_name='slug',
         label=_('Site (slug)'),
         label=_('Site (slug)'),
     )
     )
+    location_id = django_filters.ModelMultipleChoiceFilter(
+        field_name='terminations___location',
+        label=_('Location (ID)'),
+        queryset=Location.objects.all(),
+    )
     termination_a_id = django_filters.ModelMultipleChoiceFilter(
     termination_a_id = django_filters.ModelMultipleChoiceFilter(
         queryset=CircuitTermination.objects.all(),
         queryset=CircuitTermination.objects.all(),
         label=_('Termination A (ID)'),
         label=_('Termination A (ID)'),

+ 6 - 1
netbox/circuits/forms/filtersets.py

@@ -126,7 +126,7 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
             'type_id', 'status', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit',
             'type_id', 'status', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit',
             name=_('Attributes')
             name=_('Attributes')
         ),
         ),
-        FieldSet('region_id', 'site_group_id', 'site_id', name=_('Location')),
+        FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Location')),
         FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
         FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
         FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
         FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
     )
     )
@@ -181,6 +181,11 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
         },
         },
         label=_('Site')
         label=_('Site')
     )
     )
+    location_id = DynamicModelMultipleChoiceField(
+        queryset=Location.objects.all(),
+        required=False,
+        label=_('Location')
+    )
     install_date = forms.DateField(
     install_date = forms.DateField(
         label=_('Install date'),
         label=_('Install date'),
         required=False,
         required=False,

+ 22 - 2
netbox/circuits/tests/test_filtersets.py

@@ -3,8 +3,10 @@ from django.test import TestCase
 from circuits.choices import *
 from circuits.choices import *
 from circuits.filtersets import *
 from circuits.filtersets import *
 from circuits.models import *
 from circuits.models import *
-from dcim.choices import InterfaceTypeChoices
-from dcim.models import Cable, Device, DeviceRole, DeviceType, Interface, Manufacturer, Region, Site, SiteGroup
+from dcim.choices import InterfaceTypeChoices, LocationStatusChoices
+from dcim.models import (
+    Cable, Device, DeviceRole, DeviceType, Interface, Location, Manufacturer, Region, Site, SiteGroup
+)
 from ipam.models import ASN, RIR
 from ipam.models import ASN, RIR
 from netbox.choices import DistanceUnitChoices
 from netbox.choices import DistanceUnitChoices
 from tenancy.models import Tenant, TenantGroup
 from tenancy.models import Tenant, TenantGroup
@@ -225,6 +227,17 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
         )
         )
         ProviderNetwork.objects.bulk_create(provider_networks)
         ProviderNetwork.objects.bulk_create(provider_networks)
 
 
+        locations = (
+            Location.objects.create(
+                site=sites[0], name='Test Location 1', slug='test-location-1',
+                status=LocationStatusChoices.STATUS_ACTIVE,
+            ),
+            Location.objects.create(
+                site=sites[1], name='Test Location 2', slug='test-location-2',
+                status=LocationStatusChoices.STATUS_ACTIVE,
+            ),
+        )
+
         circuits = (
         circuits = (
             Circuit(
             Circuit(
                 provider=providers[0],
                 provider=providers[0],
@@ -305,7 +318,9 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
 
 
         circuit_terminations = ((
         circuit_terminations = ((
             CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A'),
             CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A'),
+            CircuitTermination(circuit=circuits[0], termination=locations[0], term_side='Z'),
             CircuitTermination(circuit=circuits[1], termination=sites[1], term_side='A'),
             CircuitTermination(circuit=circuits[1], termination=sites[1], term_side='A'),
+            CircuitTermination(circuit=circuits[1], termination=locations[1], term_side='Z'),
             CircuitTermination(circuit=circuits[2], termination=sites[2], term_side='A'),
             CircuitTermination(circuit=circuits[2], termination=sites[2], term_side='A'),
             CircuitTermination(circuit=circuits[3], termination=provider_networks[0], term_side='A'),
             CircuitTermination(circuit=circuits[3], termination=provider_networks[0], term_side='A'),
             CircuitTermination(circuit=circuits[4], termination=provider_networks[1], term_side='A'),
             CircuitTermination(circuit=circuits[4], termination=provider_networks[1], term_side='A'),
@@ -395,6 +410,11 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
         params = {'site': [sites[0].slug, sites[1].slug]}
         params = {'site': [sites[0].slug, sites[1].slug]}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
 
+    def test_location(self):
+        location_ids = Location.objects.values_list('id', flat=True)[:2]
+        params = {'location_id': location_ids}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
     def test_tenant(self):
     def test_tenant(self):
         tenants = Tenant.objects.all()[:2]
         tenants = Tenant.objects.all()[:2]
         params = {'tenant_id': [tenants[0].pk, tenants[1].pk]}
         params = {'tenant_id': [tenants[0].pk, tenants[1].pk]}