Browse Source

Closes #552: Added a None filter option for custom select fields

Jeremy Stretch 8 years ago
parent
commit
64326e7c9d
2 changed files with 20 additions and 9 deletions
  1. 15 2
      netbox/extras/filters.py
  2. 5 7
      netbox/extras/forms.py

+ 15 - 2
netbox/extras/filters.py

@@ -2,7 +2,7 @@ import django_filters
 
 
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes.models import ContentType
 
 
-from .models import CustomField
+from .models import CF_TYPE_SELECT, CustomField
 
 
 
 
 class CustomFieldFilter(django_filters.Filter):
 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.
     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):
     def filter(self, queryset, value):
+        # Skip filter on empty value
         if not value.strip():
         if not value.strip():
             return queryset
             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(
         return queryset.filter(
             custom_field_values__field__name=self.name,
             custom_field_values__field__name=self.name,
             custom_field_values__serialized_value=value,
             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)
         obj_type = ContentType.objects.get_for_model(self._meta.model)
         custom_fields = CustomField.objects.filter(obj_type=obj_type, is_filterable=True)
         custom_fields = CustomField.objects.filter(obj_type=obj_type, is_filterable=True)
         for cf in custom_fields:
         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)

+ 5 - 7
netbox/extras/forms.py

@@ -47,14 +47,12 @@ def get_custom_fields_for_model(content_type, filterable_only=False, bulk_edit=F
 
 
         # Select
         # Select
         elif cf.type == CF_TYPE_SELECT:
         elif cf.type == CF_TYPE_SELECT:
-            if bulk_edit:
+            choices = [(cfc.pk, cfc) for cfc in cf.choices.all()]
-                choices = [(cfc.pk, cfc) for cfc in cf.choices.all()]
+            if not cf.required:
-                if not cf.required:
+                choices = [(0, 'None')] + choices
-                    choices = [(0, 'None')] + choices
+            if bulk_edit or filterable_only:
                 choices = [(None, '---------')] + choices
                 choices = [(None, '---------')] + choices
-                field = forms.TypedChoiceField(choices=choices, coerce=int, required=cf.required)
+            field = forms.TypedChoiceField(choices=choices, coerce=int, required=cf.required)
-            else:
-                field = forms.ModelChoiceField(queryset=cf.choices.all(), required=cf.required)
 
 
         # URL
         # URL
         elif cf.type == CF_TYPE_URL:
         elif cf.type == CF_TYPE_URL: