Skip to content

Commit 18ac29f

Browse files
authored
18334 add location, device, site to module filters (#19312)
* 18334 add location, device, site to module filters * 18334 add location, device, site to module filters * 18334 add tests * 18334 fix tests * 18334 add site-group
1 parent fdf4286 commit 18ac29f

File tree

3 files changed

+228
-3
lines changed

3 files changed

+228
-3
lines changed

netbox/dcim/filtersets.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,10 +1337,75 @@ class ModuleFilterSet(NetBoxModelFilterSet):
13371337
lookup_expr='in',
13381338
label=_('Module bay (ID)'),
13391339
)
1340+
region_id = TreeNodeMultipleChoiceFilter(
1341+
queryset=Region.objects.all(),
1342+
field_name='device__site__region',
1343+
lookup_expr='in',
1344+
label=_('Region (ID)'),
1345+
)
1346+
region = TreeNodeMultipleChoiceFilter(
1347+
queryset=Region.objects.all(),
1348+
field_name='device__site__region',
1349+
lookup_expr='in',
1350+
to_field_name='slug',
1351+
label=_('Region (slug)'),
1352+
)
1353+
site_group_id = TreeNodeMultipleChoiceFilter(
1354+
queryset=SiteGroup.objects.all(),
1355+
field_name='device__site__group',
1356+
lookup_expr='in',
1357+
label=_('Site group (ID)'),
1358+
)
1359+
site_group = TreeNodeMultipleChoiceFilter(
1360+
queryset=SiteGroup.objects.all(),
1361+
field_name='device__site__group',
1362+
lookup_expr='in',
1363+
to_field_name='slug',
1364+
label=_('Site group (slug)'),
1365+
)
1366+
site_id = django_filters.ModelMultipleChoiceFilter(
1367+
field_name='device__site',
1368+
queryset=Site.objects.all(),
1369+
label=_('Site (ID)'),
1370+
)
1371+
site = django_filters.ModelMultipleChoiceFilter(
1372+
field_name='device__site__slug',
1373+
queryset=Site.objects.all(),
1374+
to_field_name='slug',
1375+
label=_('Site name (slug)'),
1376+
)
1377+
location_id = django_filters.ModelMultipleChoiceFilter(
1378+
field_name='device__location',
1379+
queryset=Location.objects.all(),
1380+
label=_('Location (ID)'),
1381+
)
1382+
location = django_filters.ModelMultipleChoiceFilter(
1383+
field_name='device__location__slug',
1384+
queryset=Location.objects.all(),
1385+
to_field_name='slug',
1386+
label=_('Location (slug)'),
1387+
)
1388+
rack_id = django_filters.ModelMultipleChoiceFilter(
1389+
field_name='device__rack',
1390+
queryset=Rack.objects.all(),
1391+
label=_('Rack (ID)'),
1392+
)
1393+
rack = django_filters.ModelMultipleChoiceFilter(
1394+
field_name='device__rack__name',
1395+
queryset=Rack.objects.all(),
1396+
to_field_name='name',
1397+
label=_('Rack (name)'),
1398+
)
13401399
device_id = django_filters.ModelMultipleChoiceFilter(
13411400
queryset=Device.objects.all(),
13421401
label=_('Device (ID)'),
13431402
)
1403+
device = django_filters.ModelMultipleChoiceFilter(
1404+
field_name='device__name',
1405+
queryset=Device.objects.all(),
1406+
to_field_name='name',
1407+
label=_('Device (name)'),
1408+
)
13441409
status = django_filters.MultipleChoiceFilter(
13451410
choices=ModuleStatusChoices,
13461411
null_value=None

netbox/dcim/forms/filtersets.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,8 +940,56 @@ class ModuleFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, NetBoxMo
940940
model = Module
941941
fieldsets = (
942942
FieldSet('q', 'filter_id', 'tag'),
943+
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'device_id', name=_('Location')),
943944
FieldSet('manufacturer_id', 'module_type_id', 'status', 'serial', 'asset_tag', name=_('Hardware')),
944945
)
946+
device_id = DynamicModelMultipleChoiceField(
947+
queryset=Device.objects.all(),
948+
required=False,
949+
query_params={
950+
'site_id': '$site_id',
951+
'location_id': '$location_id',
952+
'rack_id': '$rack_id',
953+
},
954+
label=_('Device')
955+
)
956+
region_id = DynamicModelMultipleChoiceField(
957+
queryset=Region.objects.all(),
958+
required=False,
959+
label=_('Region')
960+
)
961+
site_group_id = DynamicModelMultipleChoiceField(
962+
queryset=SiteGroup.objects.all(),
963+
required=False,
964+
label=_('Site group')
965+
)
966+
site_id = DynamicModelMultipleChoiceField(
967+
queryset=Site.objects.all(),
968+
required=False,
969+
query_params={
970+
'region_id': '$region_id',
971+
'group_id': '$site_group_id',
972+
},
973+
label=_('Site')
974+
)
975+
location_id = DynamicModelMultipleChoiceField(
976+
queryset=Location.objects.all(),
977+
required=False,
978+
query_params={
979+
'site_id': '$site_id',
980+
},
981+
label=_('Location')
982+
)
983+
rack_id = DynamicModelMultipleChoiceField(
984+
queryset=Rack.objects.all(),
985+
required=False,
986+
label=_('Rack'),
987+
null_option='None',
988+
query_params={
989+
'site_id': '$site_id',
990+
'location_id': '$location_id',
991+
}
992+
)
945993
manufacturer_id = DynamicModelMultipleChoiceField(
946994
queryset=Manufacturer.objects.all(),
947995
required=False,

netbox/dcim/tests/test_filtersets.py

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2729,18 +2729,95 @@ class ModuleTestCase(TestCase, ChangeLoggedFilterSetTests):
27292729

27302730
@classmethod
27312731
def setUpTestData(cls):
2732+
regions = (
2733+
Region(name='Region 1', slug='region-1'),
2734+
Region(name='Region 2', slug='region-2'),
2735+
Region(name='Region 3', slug='region-3'),
2736+
)
2737+
for region in regions:
2738+
region.save()
2739+
2740+
groups = (
2741+
SiteGroup(name='Site Group 1', slug='site-group-1'),
2742+
SiteGroup(name='Site Group 2', slug='site-group-2'),
2743+
SiteGroup(name='Site Group 3', slug='site-group-3'),
2744+
)
2745+
for group in groups:
2746+
group.save()
2747+
2748+
sites = Site.objects.bulk_create((
2749+
Site(name='Site 1', slug='site-1', region=regions[0], group=groups[0]),
2750+
Site(name='Site 2', slug='site-2', region=regions[1], group=groups[1]),
2751+
Site(name='Site 3', slug='site-3', region=regions[2], group=groups[2]),
2752+
Site(name='Site X', slug='site-x'),
2753+
))
2754+
27322755
manufacturers = (
27332756
Manufacturer(name='Manufacturer 1', slug='manufacturer-1'),
27342757
Manufacturer(name='Manufacturer 2', slug='manufacturer-2'),
27352758
Manufacturer(name='Manufacturer 3', slug='manufacturer-3'),
27362759
)
27372760
Manufacturer.objects.bulk_create(manufacturers)
27382761

2762+
device_types = (
2763+
DeviceType(manufacturer=manufacturers[0], model='Device Type 1', slug='device-type-1'),
2764+
DeviceType(manufacturer=manufacturers[1], model='Device Type 2', slug='device-type-2'),
2765+
DeviceType(manufacturer=manufacturers[2], model='Device Type 3', slug='device-type-3'),
2766+
)
2767+
DeviceType.objects.bulk_create(device_types)
2768+
2769+
roles = (
2770+
DeviceRole(name='Device Role 1', slug='device-role-1'),
2771+
DeviceRole(name='Device Role 2', slug='device-role-2'),
2772+
DeviceRole(name='Device Role 3', slug='device-role-3'),
2773+
)
2774+
DeviceRole.objects.bulk_create(roles)
2775+
2776+
locations = (
2777+
Location(name='Location 1', slug='location-1', site=sites[0]),
2778+
Location(name='Location 2', slug='location-2', site=sites[1]),
2779+
Location(name='Location 3', slug='location-3', site=sites[2]),
2780+
)
2781+
for location in locations:
2782+
location.save()
2783+
2784+
racks = (
2785+
Rack(name='Rack 1', site=sites[0]),
2786+
Rack(name='Rack 2', site=sites[1]),
2787+
Rack(name='Rack 3', site=sites[2]),
2788+
)
2789+
Rack.objects.bulk_create(racks)
2790+
27392791
devices = (
2740-
create_test_device('Test Device 1'),
2741-
create_test_device('Test Device 2'),
2742-
create_test_device('Test Device 3'),
2792+
Device(
2793+
name='Test Device 1',
2794+
device_type=device_types[0],
2795+
role=roles[0],
2796+
site=sites[0],
2797+
location=locations[0],
2798+
rack=racks[0],
2799+
status='active',
2800+
),
2801+
Device(
2802+
name='Test Device 2',
2803+
device_type=device_types[1],
2804+
role=roles[1],
2805+
site=sites[1],
2806+
location=locations[1],
2807+
rack=racks[1],
2808+
status='planned',
2809+
),
2810+
Device(
2811+
name='Test Device 3',
2812+
device_type=device_types[2],
2813+
role=roles[2],
2814+
site=sites[2],
2815+
location=locations[2],
2816+
rack=racks[2],
2817+
status='offline',
2818+
),
27432819
)
2820+
Device.objects.bulk_create(devices)
27442821

27452822
module_types = (
27462823
ModuleType(manufacturer=manufacturers[0], model='Module Type 1'),
@@ -2888,6 +2965,41 @@ def test_asset_tag(self):
28882965
params = {'asset_tag': ['A', 'B']}
28892966
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
28902967

2968+
def test_region(self):
2969+
regions = Region.objects.all()[:2]
2970+
params = {'region_id': [regions[0].pk, regions[1].pk]}
2971+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2972+
params = {'region': [regions[0].slug, regions[1].slug]}
2973+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2974+
2975+
def test_site_group(self):
2976+
site_groups = SiteGroup.objects.all()[:2]
2977+
params = {'site_group_id': [site_groups[0].pk, site_groups[1].pk]}
2978+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2979+
params = {'site_group': [site_groups[0].slug, site_groups[1].slug]}
2980+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2981+
2982+
def test_site(self):
2983+
sites = Site.objects.all()[:2]
2984+
params = {'site_id': [sites[0].pk, sites[1].pk]}
2985+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2986+
params = {'site': [sites[0].slug, sites[1].slug]}
2987+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2988+
2989+
def test_location(self):
2990+
locations = Location.objects.all()[:2]
2991+
params = {'location_id': [locations[0].pk, locations[1].pk]}
2992+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2993+
params = {'location': [locations[0].slug, locations[1].slug]}
2994+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
2995+
2996+
def test_rack(self):
2997+
racks = Rack.objects.all()[:2]
2998+
params = {'rack_id': [racks[0].pk, racks[1].pk]}
2999+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
3000+
params = {'rack': [racks[0].name, racks[1].name]}
3001+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)
3002+
28913003

28923004
class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
28933005
queryset = ConsolePort.objects.all()

0 commit comments

Comments
 (0)