diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index be1b02703..0499dcd59 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -3,7 +3,7 @@ from django.contrib.auth.models import User from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q -from extras.filters import CustomFieldFilterSet +from extras.filters import CustomFieldFilterSet, LocalConfigContextFilter from tenancy.filtersets import TenancyFilterSet from tenancy.models import Tenant from utilities.constants import COLOR_CHOICES @@ -424,7 +424,7 @@ class PlatformFilter(NameSlugSearchFilterSet): fields = ['id', 'name', 'slug', 'napalm_driver'] -class DeviceFilter(TenancyFilterSet, CustomFieldFilterSet): +class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilterSet): id__in = NumericInFilter( field_name='id', lookup_expr='in' diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 4abbcdd71..ed2f40e35 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -13,7 +13,9 @@ from taggit.forms import TagField from timezone_field import TimeZoneFormField from circuits.models import Circuit, Provider -from extras.forms import AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm +from extras.forms import ( + AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm, LocalConfigContextFilterForm +) from ipam.models import IPAddress, VLAN, VLANGroup from tenancy.forms import TenancyForm from tenancy.forms import TenancyFilterForm @@ -1675,7 +1677,7 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF ] -class DeviceFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): +class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilterForm, CustomFieldFilterForm): model = Device field_order = [ 'q', 'region', 'site', 'rack_group_id', 'rack_id', 'status', 'role', 'tenant_group', 'tenant', diff --git a/netbox/extras/filters.py b/netbox/extras/filters.py index 49e879fe4..b31271230 100644 --- a/netbox/extras/filters.py +++ b/netbox/extras/filters.py @@ -207,6 +207,20 @@ class ConfigContextFilter(django_filters.FilterSet): ) +# +# Filter for Local Config Context Data +# + +class LocalConfigContextFilter(django_filters.FilterSet): + local_context_data = django_filters.BooleanFilter( + method='_local_context_data', + label='Has local config context data', + ) + + def _local_context_data(self, queryset, name, value): + return queryset.exclude(local_context_data__isnull=value) + + class ObjectChangeFilter(django_filters.FilterSet): q = django_filters.CharFilter( method='search', diff --git a/netbox/extras/forms.py b/netbox/extras/forms.py index b06d53423..19f55c345 100644 --- a/netbox/extras/forms.py +++ b/netbox/extras/forms.py @@ -11,7 +11,8 @@ from tenancy.models import Tenant, TenantGroup from utilities.constants import COLOR_CHOICES from utilities.forms import ( add_blank_choice, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ColorSelect, - CommentField, ContentTypeSelect, FilterChoiceField, LaxURLField, JSONField, SlugField, + CommentField, ContentTypeSelect, FilterChoiceField, LaxURLField, JSONField, SlugField, StaticSelect2, + BOOLEAN_WITH_BLANK_CHOICES, ) from .constants import ( CF_FILTER_DISABLED, CF_TYPE_BOOLEAN, CF_TYPE_DATE, CF_TYPE_INTEGER, CF_TYPE_SELECT, CF_TYPE_URL, @@ -349,6 +350,20 @@ class ConfigContextFilterForm(BootstrapMixin, forms.Form): ) +# +# Filter form for local config context data +# + +class LocalConfigContextFilterForm(forms.Form): + local_context_data = forms.NullBooleanField( + required=False, + label='Has local config context data', + widget=StaticSelect2( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + + # # Image attachments #