1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

refactor lookup map logic

This commit is contained in:
John Anderson
2020-02-25 15:16:27 -05:00
parent afc8c9bfe9
commit 3b4607d30d

View File

@ -170,27 +170,8 @@ class BaseFilterSet(django_filters.FilterSet):
}, },
}) })
@classmethod @staticmethod
def get_filters(cls): def _get_filter_lookup_dict(existing_filter):
"""
Override filter generation to support dynamic lookup expressions for certain filter types.
For specific filter types, new filters are created based on defined lookup expressions in
the form `<field_name>__<lookup_expr>`
"""
# TODO: once 3.6 is the minimum required version of python, change this to a bare super() call
# We have to do it this way in py3.5 becuase of django_filters.FilterSet's use of a metaclass
filters = super(django_filters.FilterSet, cls).get_filters()
new_filters = {}
for existing_filter_name, existing_filter in filters.items():
# Loop over existing filters to extract metadata by which to create new filters
# If the filter makes use of a custom filter method or lookup expression skip it
# as we cannot sanely handle these cases in a generic mannor
if existing_filter.method is not None or existing_filter.lookup_expr not in ['exact', 'in']:
continue
# Choose the lookup expression map based on the filter type # Choose the lookup expression map based on the filter type
if isinstance(existing_filter, ( if isinstance(existing_filter, (
MultiValueDateFilter, MultiValueDateFilter,
@ -218,7 +199,35 @@ class BaseFilterSet(django_filters.FilterSet):
lookup_map = FILTER_CHAR_BASED_LOOKUP_MAP lookup_map = FILTER_CHAR_BASED_LOOKUP_MAP
else: else:
# Do not augment any other filter types with more lookup expressions lookup_map = None
return lookup_map
@classmethod
def get_filters(cls):
"""
Override filter generation to support dynamic lookup expressions for certain filter types.
For specific filter types, new filters are created based on defined lookup expressions in
the form `<field_name>__<lookup_expr>`
"""
# TODO: once 3.6 is the minimum required version of python, change this to a bare super() call
# We have to do it this way in py3.5 becuase of django_filters.FilterSet's use of a metaclass
filters = super(django_filters.FilterSet, cls).get_filters()
new_filters = {}
for existing_filter_name, existing_filter in filters.items():
# Loop over existing filters to extract metadata by which to create new filters
# If the filter makes use of a custom filter method or lookup expression skip it
# as we cannot sanely handle these cases in a generic mannor
if existing_filter.method is not None or existing_filter.lookup_expr not in ['exact', 'in']:
continue
# Choose the lookup expression map based on the filter type
lookup_map = cls._get_filter_lookup_dict(existing_filter)
if lookup_map is None:
# Do not augment this filter type with more lookup expressions
continue continue
# Get properties of the existing filter for later use # Get properties of the existing filter for later use
@ -247,6 +256,7 @@ class BaseFilterSet(django_filters.FilterSet):
) )
else: else:
# The filter field is listed in Meta.fields so we can safely rely on default behaviour # The filter field is listed in Meta.fields so we can safely rely on default behaviour
# Will raise FieldLookupError if the lookup is invalid
new_filter = cls.filter_for_field(field, field_name, lookup_expr) new_filter = cls.filter_for_field(field, field_name, lookup_expr)
except django_filters.exceptions.FieldLookupError: except django_filters.exceptions.FieldLookupError:
# The filter could not be created because the lookup expression is not supported on the field # The filter could not be created because the lookup expression is not supported on the field