From 6c0535e77c1772606a60565317b27d0d707203fd Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 30 Aug 2021 16:51:07 -0400 Subject: [PATCH] Fixes #7070: Fix exception when filtering by prefix max length in UI --- docs/release-notes/version-3.0.md | 8 ++++++++ netbox/ipam/filtersets.py | 2 +- netbox/ipam/forms.py | 4 ++-- netbox/utilities/forms/utils.py | 5 +++-- netbox/utilities/templatetags/helpers.py | 6 +++--- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index 93b8ae565..e8b9e1963 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -1,5 +1,13 @@ # NetBox v3.0 +## v2.11.12 (2021-08-23) + +### Bug Fixes + +* [#7070](https://github.com/netbox-community/netbox/issues/7070) - Fix exception when filtering by prefix max length in UI + +--- + ## v3.0.0 (2021-08-30) !!! warning "Existing Deployments Must Upgrade from v2.11" diff --git a/netbox/ipam/filtersets.py b/netbox/ipam/filtersets.py index 9525d9bb3..37a9299dc 100644 --- a/netbox/ipam/filtersets.py +++ b/netbox/ipam/filtersets.py @@ -216,7 +216,7 @@ class PrefixFilterSet(PrimaryModelFilterSet, TenancyFilterSet): children = MultiValueNumberFilter( field_name='_children' ) - mask_length = django_filters.NumberFilter( + mask_length = MultiValueNumberFilter( field_name='prefix', lookup_expr='net_mask_length' ) diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index f4977c9c3..5734fffed 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -658,11 +658,11 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilter label=_('Address family'), widget=StaticSelect() ) - mask_length = forms.ChoiceField( + mask_length = forms.MultipleChoiceField( required=False, choices=PREFIX_MASK_LENGTH_CHOICES, label=_('Mask length'), - widget=StaticSelect() + widget=StaticSelectMultiple() ) vrf_id = DynamicModelMultipleChoiceField( queryset=VRF.objects.all(), diff --git a/netbox/utilities/forms/utils.py b/netbox/utilities/forms/utils.py index 5a5f87ed8..0121b250c 100644 --- a/netbox/utilities/forms/utils.py +++ b/netbox/utilities/forms/utils.py @@ -119,13 +119,14 @@ def get_selected_values(form, field_name): """ if not hasattr(form, 'cleaned_data'): form.is_valid() + filter_data = form.cleaned_data.get(field_name) # Selection field if hasattr(form.fields[field_name], 'choices'): try: choices = dict(unpack_grouped_choices(form.fields[field_name].choices)) return [ - label for value, label in choices.items() if value in form.cleaned_data[field_name] + label for value, label in choices.items() if str(value) in filter_data ] except TypeError: # Field uses dynamic choices. Show all that have been populated. @@ -134,7 +135,7 @@ def get_selected_values(form, field_name): ] # Non-selection field - return [str(form.cleaned_data[field_name])] + return [str(filter_data)] def add_blank_choice(choices): diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py index 4784fae30..48b5ab13f 100644 --- a/netbox/utilities/templatetags/helpers.py +++ b/netbox/utilities/templatetags/helpers.py @@ -411,16 +411,16 @@ def applied_filters(form, query_params): Display the active filters for a given filter form. """ form.is_valid() + querydict = query_params.copy() applied_filters = [] for filter_name in form.changed_data: - if filter_name not in query_params: + if filter_name not in querydict: continue bound_field = form.fields[filter_name].get_bound_field(form, filter_name) - querydict = query_params.copy() querydict.pop(filter_name) - display_value = ', '.join(get_selected_values(form, filter_name)) + display_value = ', '.join([str(v) for v in get_selected_values(form, filter_name)]) applied_filters.append({ 'name': filter_name,