From fd9b2f2fdaca92e116963ad7e2ec78413fe6c0de Mon Sep 17 00:00:00 2001 From: John Anderson Date: Thu, 15 Nov 2018 00:42:01 -0500 Subject: [PATCH] cleanup component filters and UI filter forms for device and device type - #2583 --- netbox/dcim/filters.py | 104 +++++++++++++----------------- netbox/dcim/forms.py | 92 +++++++++++++++++--------- netbox/project-static/js/forms.js | 2 - netbox/utilities/forms.py | 5 ++ 4 files changed, 113 insertions(+), 90 deletions(-) diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index aa18f46c6..50929512e 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -299,7 +299,7 @@ class ManufacturerFilter(django_filters.FilterSet): fields = ['name', 'slug'] -class DeviceTypeFilter(CustomFieldFilterSet, django_filters.FilterSet): +class DeviceTypeFilter(CustomFieldFilterSet): id__in = NumericInFilter( field_name='id', lookup_expr='in' @@ -318,27 +318,27 @@ class DeviceTypeFilter(CustomFieldFilterSet, django_filters.FilterSet): to_field_name='slug', label='Manufacturer (slug)', ) - console_ports = django_filters.CharFilter( + console_ports = django_filters.BooleanFilter( method='_console_ports', label='Has console ports', ) - console_server_ports = django_filters.CharFilter( + console_server_ports = django_filters.BooleanFilter( method='_console_server_ports', label='Has console server ports', ) - power_ports = django_filters.CharFilter( + power_ports = django_filters.BooleanFilter( method='_power_ports', label='Has power ports', ) - power_outlets = django_filters.CharFilter( + power_outlets = django_filters.BooleanFilter( method='_power_outlets', label='Has power outlets', ) - interfaces = django_filters.CharFilter( + interfaces = django_filters.BooleanFilter( method='_interfaces', label='Has interfaces', ) - pass_through_ports = django_filters.CharFilter( + pass_through_ports = django_filters.BooleanFilter( method='_pass_through_ports', label='Has pass-through ports', ) @@ -361,30 +361,24 @@ class DeviceTypeFilter(CustomFieldFilterSet, django_filters.FilterSet): ) def _console_ports(self, queryset, name, value): - value = value.strip() - return queryset.exclude(consoleport_templates__isnull=bool(value)) + return queryset.exclude(consoleport_templates__isnull=value) def _console_server_ports(self, queryset, name, value): - value = value.strip() - return queryset.exclude(consoleserverport_templates__isnull=bool(value)) + return queryset.exclude(consoleserverport_templates__isnull=value) def _power_ports(self, queryset, name, value): - value = value.strip() - return queryset.exclude(powerport_templates__isnull=bool(value)) + return queryset.exclude(powerport_templates__isnull=value) def _power_outlets(self, queryset, name, value): - value = value.strip() - return queryset.exclude(poweroutlet_templates__isnull=bool(value)) + return queryset.exclude(poweroutlet_templates__isnull=value) def _interfaces(self, queryset, name, value): - value = value.strip() - return queryset.exclude(interface_templates__isnull=bool(value)) + return queryset.exclude(interface_templates__isnull=value) def _pass_through_ports(self, queryset, name, value): - value = value.strip() return queryset.exclude( - frontport_templates__isnull=bool(value), - rearport_templates__isnull=bool(value) + frontport_templates__isnull=value, + rearport_templates__isnull=value ) @@ -477,7 +471,7 @@ class PlatformFilter(django_filters.FilterSet): fields = ['name', 'slug'] -class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet): +class DeviceFilter(CustomFieldFilterSet): id__in = NumericInFilter( field_name='id', lookup_expr='in' @@ -582,30 +576,6 @@ class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet): field_name='device_type__is_full_depth', label='Is full depth', ) - console_ports = django_filters.CharFilter( - method='_console_ports', - label='Has console ports', - ) - console_server_ports = django_filters.CharFilter( - method='_console_server_ports', - label='Has console server ports', - ) - power_ports = django_filters.CharFilter( - method='_power_ports', - label='Has power ports', - ) - power_outlets = django_filters.CharFilter( - method='_power_outlets', - label='Has power outlets', - ) - interfaces = django_filters.CharFilter( - method='_interfaces', - label='Has interfaces', - ) - pass_through_ports = django_filters.CharFilter( - method='_pass_through_ports', - label='Has pass-through ports', - ) mac_address = django_filters.CharFilter( method='_mac_address', label='MAC address', @@ -619,6 +589,30 @@ class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet): queryset=VirtualChassis.objects.all(), label='Virtual chassis (ID)', ) + console_ports = django_filters.BooleanFilter( + method='_console_ports', + label='Has console ports', + ) + console_server_ports = django_filters.BooleanFilter( + method='_console_server_ports', + label='Has console server ports', + ) + power_ports = django_filters.BooleanFilter( + method='_power_ports', + label='Has power ports', + ) + power_outlets = django_filters.BooleanFilter( + method='_power_outlets', + label='Has power outlets', + ) + interfaces = django_filters.BooleanFilter( + method='_interfaces', + label='Has interfaces', + ) + pass_through_ports = django_filters.BooleanFilter( + method='_pass_through_ports', + label='Has pass-through ports', + ) tag = TagFilter() class Meta: @@ -669,30 +663,24 @@ class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet): ) def _console_ports(self, queryset, name, value): - value = value.strip() - return queryset.exclude(consoleports__isnull=bool(value)) + return queryset.exclude(consoleports__isnull=value) def _console_server_ports(self, queryset, name, value): - value = value.strip() - return queryset.exclude(consoleserverports__isnull=bool(value)) + return queryset.exclude(consoleserverports__isnull=value) def _power_ports(self, queryset, name, value): - value = value.strip() - return queryset.exclude(powerports__isnull=bool(value)) + return queryset.exclude(powerports__isnull=value) def _power_outlets(self, queryset, name, value): - value = value.strip() - return queryset.exclude(poweroutlets__isnull=bool(value)) + return queryset.exclude(poweroutlets_isnull=value) def _interfaces(self, queryset, name, value): - value = value.strip() - return queryset.exclude(interfaces__isnull=bool(value)) + return queryset.exclude(interfaces__isnull=value) def _pass_through_ports(self, queryset, name, value): - value = value.strip() return queryset.exclude( - frontports__isnull=bool(value), - rearports__isnull=bool(value) + frontports__isnull=value, + rearports__isnull=value ) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 83cdff29e..27f03ef3b 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -19,7 +19,7 @@ from utilities.forms import ( BulkEditNullBooleanSelect, ChainedFieldsMixin, ChainedModelChoiceField, ColorSelect, CommentField, ComponentForm, ConfirmationForm, ContentTypeSelect, CSVChoiceField, ExpandableNameField, FilterChoiceField, FilterTreeNodeMultipleChoiceField, FlexibleModelChoiceField, JSONField, Livesearch, SelectWithPK, SmallTextarea, - SlugField, COLOR_CHOICES, + SlugField, BOOLEAN_WITH_BLANK_CHOICES, COLOR_CHOICES, ) from virtualization.models import Cluster @@ -650,35 +650,41 @@ class DeviceTypeFilterForm(BootstrapMixin, CustomFieldFilterForm): queryset=Manufacturer.objects.annotate(filter_count=Count('device_types')), to_field_name='slug' ) - console_ports = forms.BooleanField( - required=False, - label='Has console ports' - ) - console_server_ports = forms.BooleanField( - required=False, - label='Has console server ports' - ) - power_ports = forms.BooleanField( - required=False, - label='Has power ports' - ) - power_outlets = forms.BooleanField( - required=False, - label='Has power outlets' - ) - interfaces = forms.BooleanField( - required=False, - label='Has interfaces' - ) - pass_through_ports = forms.BooleanField( - required=False, - label='Has pass-through ports' - ) subdevice_role = forms.NullBooleanField( required=False, label='Subdevice role', widget=forms.Select(choices=add_blank_choice(SUBDEVICE_ROLE_CHOICES)) ) + console_ports = forms.NullBooleanField( + required=False, + label='Has console ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + console_server_ports = forms.NullBooleanField( + required=False, + label='Has console server ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + power_ports = forms.NullBooleanField( + required=False, + label='Has power ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + power_outlets = forms.NullBooleanField( + required=False, + label='Has power outlets', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + interfaces = forms.NullBooleanField( + required=False, + label='Has interfaces', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + pass_through_ports = forms.NullBooleanField( + required=False, + label='Has pass-through ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) # @@ -1316,11 +1322,37 @@ class DeviceFilterForm(BootstrapMixin, CustomFieldFilterForm): has_primary_ip = forms.NullBooleanField( required=False, label='Has a primary IP', - widget=forms.Select(choices=[ - ('', '---------'), - ('True', 'Yes'), - ('False', 'No'), - ]) + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + console_ports = forms.NullBooleanField( + required=False, + label='Has console ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + console_server_ports = forms.NullBooleanField( + required=False, + label='Has console server ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + power_ports = forms.NullBooleanField( + required=False, + label='Has power ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + power_outlets = forms.NullBooleanField( + required=False, + label='Has power outlets', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + interfaces = forms.NullBooleanField( + required=False, + label='Has interfaces', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + pass_through_ports = forms.NullBooleanField( + required=False, + label='Has pass-through ports', + widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) ) diff --git a/netbox/project-static/js/forms.js b/netbox/project-static/js/forms.js index a494664c7..89bc3aee1 100644 --- a/netbox/project-static/js/forms.js +++ b/netbox/project-static/js/forms.js @@ -110,9 +110,7 @@ $(document).ready(function() { var conditional = attr.name.split("data-url-conditional-append-")[1].split("__"); var field = $("#id_" + conditional[0]); var field_value = conditional[1]; - console.log($('option:selected', field).attr('api-value')); if ($('option:selected', field).attr('api-value') === field_value){ - console.log(attr.value); rendered_url = rendered_url + attr.value; } } diff --git a/netbox/utilities/forms.py b/netbox/utilities/forms.py index 51e553cf9..181221fe3 100644 --- a/netbox/utilities/forms.py +++ b/netbox/utilities/forms.py @@ -42,6 +42,11 @@ NUMERIC_EXPANSION_PATTERN = r'\[((?:\d+[?:,-])+\d+)\]' ALPHANUMERIC_EXPANSION_PATTERN = r'\[((?:[a-zA-Z0-9]+[?:,-])+[a-zA-Z0-9]+)\]' IP4_EXPANSION_PATTERN = r'\[((?:[0-9]{1,3}[?:,-])+[0-9]{1,3})\]' IP6_EXPANSION_PATTERN = r'\[((?:[0-9a-f]{1,4}[?:,-])+[0-9a-f]{1,4})\]' +BOOLEAN_WITH_BLANK_CHOICES = ( + ('', '---------'), + ('True', 'Yes'), + ('False', 'No'), +) def parse_numeric_range(string, base=10):