Enable filtering device components by location

This commit is contained in:
jeremystretch 2021-08-24 21:10:30 -04:00
parent 125a562189
commit d184ed4712
3 changed files with 198 additions and 76 deletions

View File

@ -831,6 +831,17 @@ class DeviceComponentFilterSet(django_filters.FilterSet):
to_field_name='slug',
label='Site name (slug)',
)
location_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__location',
queryset=Location.objects.all(),
label='Location (ID)',
)
location = django_filters.ModelMultipleChoiceFilter(
field_name='device__location__slug',
queryset=Location.objects.all(),
to_field_name='slug',
label='Location (slug)',
)
device_id = django_filters.ModelMultipleChoiceFilter(
queryset=Device.objects.all(),
label='Device (ID)',
@ -1053,39 +1064,6 @@ class InventoryItemFilterSet(PrimaryModelFilterSet, DeviceComponentFilterSet):
method='search',
label='Search',
)
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='device__site__region',
lookup_expr='in',
label='Region (ID)',
)
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='device__site__region',
lookup_expr='in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__site',
queryset=Site.objects.all(),
label='Site (ID)',
)
site = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__slug',
queryset=Site.objects.all(),
to_field_name='slug',
label='Site name (slug)',
)
device_id = django_filters.ModelChoiceFilter(
queryset=Device.objects.all(),
label='Device (ID)',
)
device = django_filters.ModelChoiceFilter(
queryset=Device.objects.all(),
to_field_name='name',
label='Device (name)',
)
parent_id = django_filters.ModelMultipleChoiceFilter(
queryset=InventoryItem.objects.all(),
label='Parent inventory item (ID)',

View File

@ -91,11 +91,21 @@ class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
label=_('Site'),
fetch_trigger='open'
)
location_id = DynamicModelMultipleChoiceField(
queryset=Location.objects.all(),
required=False,
query_params={
'site_id': '$site_id',
},
label=_('Location'),
fetch_trigger='open'
)
device_id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(),
required=False,
query_params={
'site_id': '$site_id'
'site_id': '$site_id',
'location_id': '$location_id',
},
label=_('Device'),
fetch_trigger='open'
@ -2744,7 +2754,7 @@ class ConsolePortFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'type', 'speed'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
type = forms.MultipleChoiceField(
choices=ConsolePortTypeChoices,
@ -2850,7 +2860,7 @@ class ConsoleServerPortFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'type', 'speed'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
type = forms.MultipleChoiceField(
choices=ConsolePortTypeChoices,
@ -2956,7 +2966,7 @@ class PowerPortFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'type'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
type = forms.MultipleChoiceField(
choices=PowerPortTypeChoices,
@ -3061,7 +3071,7 @@ class PowerOutletFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'type'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
type = forms.MultipleChoiceField(
choices=PowerOutletTypeChoices,
@ -3233,7 +3243,7 @@ class InterfaceFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'type', 'enabled', 'mgmt_only', 'mac_address'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
type = forms.MultipleChoiceField(
choices=InterfaceTypeChoices,
@ -3591,7 +3601,7 @@ class FrontPortFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'type', 'color'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
model = FrontPort
type = forms.MultipleChoiceField(
@ -3780,7 +3790,7 @@ class RearPortFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'type', 'color'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
type = forms.MultipleChoiceField(
choices=PortTypeChoices,
@ -3881,7 +3891,7 @@ class DeviceBayFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
tag = TagFilterField(model)
@ -4132,7 +4142,7 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
field_groups = [
['q', 'tag'],
['name', 'label', 'manufacturer_id', 'serial', 'asset_tag', 'discovered'],
['region_id', 'site_group_id', 'site_id', 'device_id'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'device_id'],
]
manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(),

View File

@ -1512,10 +1512,18 @@ class ConsolePortTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
Device(name=None, device_type=device_type, device_role=device_role, site=sites[3]), # For cable connections
)
Device.objects.bulk_create(devices)
@ -1584,6 +1592,13 @@ class ConsolePortTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'device': [devices[0].name, devices[1].name]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_cabled(self):
params = {'cabled': 'true'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
@ -1624,10 +1639,18 @@ class ConsoleServerPortTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
Device(name=None, device_type=device_type, device_role=device_role, site=sites[3]), # For cable connections
)
Device.objects.bulk_create(devices)
@ -1689,6 +1712,13 @@ class ConsoleServerPortTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_device(self):
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
@ -1736,10 +1766,18 @@ class PowerPortTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
Device(name=None, device_type=device_type, device_role=device_role, site=sites[3]), # For cable connections
)
Device.objects.bulk_create(devices)
@ -1809,6 +1847,13 @@ class PowerPortTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_device(self):
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
@ -1856,10 +1901,18 @@ class PowerOutletTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
Device(name=None, device_type=device_type, device_role=device_role, site=sites[3]), # For cable connections
)
Device.objects.bulk_create(devices)
@ -1925,6 +1978,13 @@ class PowerOutletTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_device(self):
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
@ -1972,10 +2032,18 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
Device(name=None, device_type=device_type, device_role=device_role, site=sites[3]), # For cable connections
)
Device.objects.bulk_create(devices)
@ -2082,6 +2150,13 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_device(self):
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
@ -2143,10 +2218,18 @@ class FrontPortTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
Device(name=None, device_type=device_type, device_role=device_role, site=sites[3]), # For cable connections
)
Device.objects.bulk_create(devices)
@ -2217,6 +2300,13 @@ class FrontPortTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_device(self):
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
@ -2264,10 +2354,18 @@ class RearPortTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
Device(name=None, device_type=device_type, device_role=device_role, site=sites[3]), # For cable connections
)
Device.objects.bulk_create(devices)
@ -2332,6 +2430,13 @@ class RearPortTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_device(self):
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
@ -2379,10 +2484,18 @@ class DeviceBayTestCase(TestCase, ChangeLoggedFilterSetTests):
device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Model 1', slug='model-1')
device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
)
Device.objects.bulk_create(devices)
@ -2426,6 +2539,13 @@ class DeviceBayTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_device(self):
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
@ -2474,10 +2594,18 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests):
)
Site.objects.bulk_create(sites)
locations = (
Location(name='Location 1', slug='location-1', site=sites[0]),
Location(name='Location 2', slug='location-2', site=sites[1]),
Location(name='Location 3', slug='location-3', site=sites[2]),
)
for location in locations:
location.save()
devices = (
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2]),
Device(name='Device 1', device_type=device_type, device_role=device_role, site=sites[0], location=locations[0]),
Device(name='Device 2', device_type=device_type, device_role=device_role, site=sites[1], location=locations[1]),
Device(name='Device 3', device_type=device_type, device_role=device_role, site=sites[2], location=locations[2]),
)
Device.objects.bulk_create(devices)
@ -2541,13 +2669,19 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'site': [sites[0].slug, sites[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_location(self):
locations = Location.objects.all()[:2]
params = {'location_id': [locations[0].pk, locations[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
params = {'location': [locations[0].slug, locations[1].slug]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_device(self):
# TODO: Allow multiple values
device = Device.objects.first()
params = {'device_id': device.pk}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'device': device.name}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
devices = Device.objects.all()[:2]
params = {'device_id': [devices[0].pk, devices[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
params = {'device': [devices[0].name, devices[1].name]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_parent_id(self):
parent_items = InventoryItem.objects.filter(parent__isnull=True)[:2]