From 64326e7c9da59e316b4d88ad64b16e00e55eb985 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 16 Sep 2016 13:41:53 -0400 Subject: [PATCH] Closes #552: Added a None filter option for custom select fields --- netbox/extras/filters.py | 17 +++++++++++++++-- netbox/extras/forms.py | 12 +++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/netbox/extras/filters.py b/netbox/extras/filters.py index d8ccbf986..bcd9f175f 100644 --- a/netbox/extras/filters.py +++ b/netbox/extras/filters.py @@ -2,7 +2,7 @@ import django_filters from django.contrib.contenttypes.models import ContentType -from .models import CustomField +from .models import CF_TYPE_SELECT, CustomField class CustomFieldFilter(django_filters.Filter): @@ -10,9 +10,22 @@ class CustomFieldFilter(django_filters.Filter): Filter objects by the presence of a CustomFieldValue. The filter's name is used as the CustomField name. """ + def __init__(self, cf_type, *args, **kwargs): + self.cf_type = cf_type + super(CustomFieldFilter, self).__init__(*args, **kwargs) + def filter(self, queryset, value): + # Skip filter on empty value if not value.strip(): return queryset + # Treat 0 as None for Select fields + try: + if self.cf_type == CF_TYPE_SELECT and int(value) == 0: + return queryset.exclude( + custom_field_values__field__name=self.name, + ) + except ValueError: + pass return queryset.filter( custom_field_values__field__name=self.name, custom_field_values__serialized_value=value, @@ -30,4 +43,4 @@ class CustomFieldFilterSet(django_filters.FilterSet): obj_type = ContentType.objects.get_for_model(self._meta.model) custom_fields = CustomField.objects.filter(obj_type=obj_type, is_filterable=True) for cf in custom_fields: - self.filters['cf_{}'.format(cf.name)] = CustomFieldFilter(name=cf.name) + self.filters['cf_{}'.format(cf.name)] = CustomFieldFilter(name=cf.name, cf_type=cf.type) diff --git a/netbox/extras/forms.py b/netbox/extras/forms.py index 8ec70d2e8..06c5403c6 100644 --- a/netbox/extras/forms.py +++ b/netbox/extras/forms.py @@ -47,14 +47,12 @@ def get_custom_fields_for_model(content_type, filterable_only=False, bulk_edit=F # Select elif cf.type == CF_TYPE_SELECT: - if bulk_edit: - choices = [(cfc.pk, cfc) for cfc in cf.choices.all()] - if not cf.required: - choices = [(0, 'None')] + choices + choices = [(cfc.pk, cfc) for cfc in cf.choices.all()] + if not cf.required: + choices = [(0, 'None')] + choices + if bulk_edit or filterable_only: choices = [(None, '---------')] + choices - field = forms.TypedChoiceField(choices=choices, coerce=int, required=cf.required) - else: - field = forms.ModelChoiceField(queryset=cf.choices.all(), required=cf.required) + field = forms.TypedChoiceField(choices=choices, coerce=int, required=cf.required) # URL elif cf.type == CF_TYPE_URL: