diff --git a/docs/release-notes/version-2.6.md b/docs/release-notes/version-2.6.md index 33b59b5d9..38e3de632 100644 --- a/docs/release-notes/version-2.6.md +++ b/docs/release-notes/version-2.6.md @@ -2,6 +2,7 @@ ## Enhancements +* [#3062](https://github.com/netbox-community/netbox/issues/3062) - Add `assigned_to_interface` filter for IP addresses * [#3461](https://github.com/netbox-community/netbox/issues/3461) - Fail gracefully on custom link rendering exception * [#3705](https://github.com/netbox-community/netbox/issues/3705) - Provide request context when executing custom scripts * [#3762](https://github.com/netbox-community/netbox/issues/3762) - Add date/time picker widgets diff --git a/netbox/ipam/filters.py b/netbox/ipam/filters.py index c54ba2f62..1f8fd2caf 100644 --- a/netbox/ipam/filters.py +++ b/netbox/ipam/filters.py @@ -309,6 +309,10 @@ class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt queryset=Interface.objects.all(), label='Interface (ID)', ) + assigned_to_interface = django_filters.BooleanFilter( + method='_assigned_to_interface', + label='Is assigned to an interface', + ) status = django_filters.MultipleChoiceFilter( choices=IPADDRESS_STATUS_CHOICES, null_value=None @@ -366,6 +370,9 @@ class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt except Device.DoesNotExist: return queryset.none() + def _assigned_to_interface(self, queryset, name, value): + return queryset.exclude(interface__isnull=value) + class VLANGroupFilter(NameSlugSearchFilterSet): site_id = django_filters.ModelMultipleChoiceFilter( diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index a95967b20..44056653b 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -938,7 +938,8 @@ class IPAddressAssignForm(BootstrapMixin, forms.Form): class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): model = IPAddress field_order = [ - 'q', 'parent', 'family', 'mask_length', 'vrf_id', 'status', 'role', 'tenant_group', 'tenant', + 'q', 'parent', 'family', 'mask_length', 'vrf_id', 'status', 'role', 'assigned_to_interface', 'tenant_group', + 'tenant', ] q = forms.CharField( required=False, @@ -984,6 +985,13 @@ class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterFo required=False, widget=StaticSelect2Multiple() ) + assigned_to_interface = forms.NullBooleanField( + required=False, + label='Assigned to an interface', + widget=StaticSelect2( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) #