diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 433e08960..83b512445 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -93,6 +93,17 @@ class SiteFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet class RackGroupFilter(NameSlugSearchFilterSet): + region_id = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='site__region__in', + label='Region (ID)', + ) + region = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='site__region__in', + to_field_name='slug', + label='Region (slug)', + ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label='Site (ID)', @@ -125,6 +136,17 @@ class RackFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet method='search', label='Search', ) + region_id = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='site__region__in', + label='Region (ID)', + ) + region = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='site__region__in', + to_field_name='slug', + label='Region (slug)', + ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label='Site (ID)', @@ -831,6 +853,28 @@ class InventoryItemFilter(DeviceComponentFilterSet): method='search', label='Search', ) + region_id = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='device__site__region__in', + label='Region (ID)', + ) + region = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='device__site__region__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)', @@ -880,6 +924,17 @@ class VirtualChassisFilter(django_filters.FilterSet): method='search', label='Search', ) + region_id = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='master__site__region__in', + label='Region (ID)', + ) + region = TreeNodeMultipleChoiceFilter( + queryset=Region.objects.all(), + field_name='master__site__region__in', + to_field_name='slug', + label='Region (slug)', + ) site_id = django_filters.ModelMultipleChoiceFilter( field_name='master__site', queryset=Site.objects.all(), diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 429d26c60..8217dc6f4 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -364,6 +364,18 @@ class RackGroupCSVForm(forms.ModelForm): class RackGroupFilterForm(BootstrapMixin, forms.Form): + region = FilterChoiceField( + queryset=Region.objects.all(), + to_field_name='slug', + required=False, + widget=APISelectMultiple( + api_url="/api/dcim/regions/", + value_field="slug", + filter_for={ + 'site': 'region' + } + ) + ) site = FilterChoiceField( queryset=Site.objects.all(), to_field_name='slug', @@ -635,11 +647,23 @@ class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): model = Rack - field_order = ['q', 'site', 'group_id', 'status', 'role', 'tenant_group', 'tenant'] + field_order = ['q', 'region', 'site', 'group_id', 'status', 'role', 'tenant_group', 'tenant'] q = forms.CharField( required=False, label='Search' ) + region = FilterChoiceField( + queryset=Region.objects.all(), + to_field_name='slug', + required=False, + widget=APISelectMultiple( + api_url="/api/dcim/regions/", + value_field="slug", + filter_for={ + 'site': 'region' + } + ) + ) site = FilterChoiceField( queryset=Site.objects.all(), to_field_name='slug', @@ -3386,6 +3410,29 @@ class InventoryItemFilterForm(BootstrapMixin, forms.Form): required=False, label='Search' ) + region = FilterChoiceField( + queryset=Region.objects.all(), + to_field_name='slug', + required=False, + widget=APISelectMultiple( + api_url="/api/dcim/regions/", + value_field="slug", + filter_for={ + 'site': 'region' + } + ) + ) + site = FilterChoiceField( + queryset=Site.objects.all(), + to_field_name='slug', + widget=APISelectMultiple( + api_url="/api/dcim/sites/", + value_field="slug", + filter_for={ + 'device_id': 'site' + } + ) + ) device_id = FilterChoiceField( queryset=Device.objects.all(), required=False, @@ -3551,6 +3598,18 @@ class VirtualChassisFilterForm(BootstrapMixin, CustomFieldFilterForm): required=False, label='Search' ) + region = FilterChoiceField( + queryset=Region.objects.all(), + to_field_name='slug', + required=False, + widget=APISelectMultiple( + api_url="/api/dcim/regions/", + value_field="slug", + filter_for={ + 'site': 'region' + } + ) + ) site = FilterChoiceField( queryset=Site.objects.all(), to_field_name='slug',