Automatically add additional lookup filters for custom fields

This commit is contained in:
jeremystretch 2021-10-28 16:09:36 -04:00
parent 7c60089692
commit 2e0f15b35f
2 changed files with 22 additions and 5 deletions

View File

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

View File

@ -84,6 +84,7 @@ class BaseFilterSet(django_filters.FilterSet):
def _get_filter_lookup_dict(existing_filter): def _get_filter_lookup_dict(existing_filter):
# 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, (
django_filters.NumberFilter,
filters.MultiValueDateFilter, filters.MultiValueDateFilter,
filters.MultiValueDateTimeFilter, filters.MultiValueDateTimeFilter,
filters.MultiValueNumberFilter, filters.MultiValueNumberFilter,
@ -151,6 +152,10 @@ class BaseFilterSet(django_filters.FilterSet):
distinct=existing_filter.distinct, distinct=existing_filter.distinct,
**existing_filter.extra **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: 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 # Will raise FieldLookupError if the lookup is invalid
@ -222,9 +227,14 @@ class PrimaryModelFilterSet(ChangeLoggedModelFilterSet):
custom_field_filters = {} custom_field_filters = {}
for custom_field in custom_fields: for custom_field in custom_fields:
cf_filter = custom_field.to_filter() filter_name = f'cf_{custom_field.name}'
if cf_filter: filter_instance = custom_field.to_filter()
custom_field_filters[f'cf_{custom_field.name}'] = cf_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) self.filters.update(custom_field_filters)