Bladeren bron

Automatically add additional lookup filters for custom fields

jeremystretch 4 jaren geleden
bovenliggende
commit
2e0f15b35f
2 gewijzigde bestanden met toevoegingen van 22 en 5 verwijderingen
  1. 9 2
      netbox/extras/models/customfields.py
  2. 13 3
      netbox/netbox/filtersets.py

+ 9 - 2
netbox/extras/models/customfields.py

@@ -309,13 +309,17 @@ class CustomField(ChangeLoggedModel):
 
         return field
 
-    def to_filter(self):
+    def to_filter(self, lookup_expr=None):
         """
         Return a django_filters Filter instance suitable for this field type.
+
+        :param lookup_expr: Custom lookup expression (optional)
         """
         kwargs = {
             'field_name': f'custom_field_data__{self.name}'
         }
+        if lookup_expr is not None:
+            kwargs['lookup_expr'] = lookup_expr
 
         # Text/URL
         if self.type in (
@@ -354,7 +358,10 @@ class CustomField(ChangeLoggedModel):
         else:
             return None
 
-        return filter_class(**kwargs)
+        filter_instance = filter_class(**kwargs)
+        filter_instance.custom_field = self
+
+        return filter_instance
 
     def validate(self, value):
         """

+ 13 - 3
netbox/netbox/filtersets.py

@@ -84,6 +84,7 @@ class BaseFilterSet(django_filters.FilterSet):
     def _get_filter_lookup_dict(existing_filter):
         # Choose the lookup expression map based on the filter type
         if isinstance(existing_filter, (
+            django_filters.NumberFilter,
             filters.MultiValueDateFilter,
             filters.MultiValueDateTimeFilter,
             filters.MultiValueNumberFilter,
@@ -151,6 +152,10 @@ class BaseFilterSet(django_filters.FilterSet):
                         distinct=existing_filter.distinct,
                         **existing_filter.extra
                     )
+                elif hasattr(existing_filter, 'custom_field'):
+                    # Filter is for a custom field
+                    custom_field = existing_filter.custom_field
+                    new_filter = custom_field.to_filter(lookup_expr=lookup_expr)
                 else:
                     # The filter field is listed in Meta.fields so we can safely rely on default behaviour
                     # Will raise FieldLookupError if the lookup is invalid
@@ -222,9 +227,14 @@ class PrimaryModelFilterSet(ChangeLoggedModelFilterSet):
 
         custom_field_filters = {}
         for custom_field in custom_fields:
-            cf_filter = custom_field.to_filter()
-            if cf_filter:
-                custom_field_filters[f'cf_{custom_field.name}'] = cf_filter
+            filter_name = f'cf_{custom_field.name}'
+            filter_instance = custom_field.to_filter()
+            if filter_instance:
+                custom_field_filters[filter_name] = filter_instance
+
+                # Add relevant additional lookups
+                additional_lookups = self.get_additional_lookups(filter_name, filter_instance)
+                custom_field_filters.update(additional_lookups)
 
         self.filters.update(custom_field_filters)