Skip to content

Commit 2fc13df

Browse files
authored
Merge pull request #26 from adesor/value-transformations
Add value transformation logic
2 parents 7c91673 + 62d3e11 commit 2fc13df

File tree

3 files changed

+23
-147
lines changed

3 files changed

+23
-147
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ installed using python-pip like `pip install drf-url-filters`.
1717

1818
2. Add `filters` in INSTALLED_APPS of settings.py file of django project.
1919

20-
**How it works?**
20+
**How it works**
2121

2222
1. Your View or ModelViewSet should inherit `FiltersMixin` from
2323
`filters.mixins.FiltersMixin`.
@@ -26,6 +26,11 @@ installed using python-pip like `pip install drf-url-filters`.
2626
have a dict mapping `filter_mappings` which converts incoming query parameters
2727
to query you want to make on the column name on the queryset.
2828

29+
3. Optionally, to perform any preprocessing on the incoming values for
30+
query params, add another dict `filter_value_transformations` which maps
31+
incoming query parameters to functions that should be applied to the values
32+
corresponding to them. The resultant value is used in the final filtering.
33+
2934
# validations.py
3035

3136
```python
@@ -46,6 +51,7 @@ players_query_schema = base_query_param_schema.extend(
4651
"team_id": CSVofIntegers(), # /?team_id=1,2,3
4752
"install_ts": DatetimeWithTZ(),
4853
"update_ts": DatetimeWithTZ(),
54+
"taller_than": IntegerLike(),
4955
}
5056
)
5157
```
@@ -88,6 +94,11 @@ class PlayersViewSet(FiltersMixin, viewsets.ModelViewSet):
8894
'update_ts': 'update_ts',
8995
'update_ts__gte': 'update_ts__gte',
9096
'update_ts__lte': 'update_ts__lte',
97+
'taller_than': 'height__gte',
98+
}
99+
100+
field_value_transformations = {
101+
'taller_than': lambda val: val / 30.48 # cm to ft
91102
}
92103

93104
# add validation on filters

docs/README.md

Lines changed: 0 additions & 138 deletions
This file was deleted.

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../README.md

filters/mixins.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def __get_queryset_filters(self, query_params, *args, **kwargs):
2626

2727
if getattr(self, 'filter_mappings', None) and query_params:
2828
filter_mappings = self.filter_mappings
29+
value_transformations = getattr(self, 'filter_value_transformations', {})
2930

3031
try:
3132
# check and raise 400_BAD_REQUEST for invalid query params
@@ -46,15 +47,16 @@ def __get_queryset_filters(self, query_params, *args, **kwargs):
4647
# [1] ~ sign is used to exclude a filter.
4748
is_exclude = '~' in query
4849
if query in self.filter_mappings and value:
49-
query = filter_mappings[query]
50+
query_filter = filter_mappings[query]
51+
transform_value = value_transformations.get(query, lambda val: val)
52+
transformed_value = transform_value(value)
5053
# [2] multiple options is filter values will execute as `IN` query
51-
if isinstance(value, list):
52-
query += '__in'
53-
if value:
54-
if is_exclude:
55-
excludes.append((query, value))
56-
else:
57-
filters.append((query, value))
54+
if isinstance(value, list) and not query_filter.endswith('__in'):
55+
query_filter += '__in'
56+
if is_exclude:
57+
excludes.append((query_filter, transformed_value))
58+
else:
59+
filters.append((query_filter, transformed_value))
5860

5961
return dict(filters), dict(excludes)
6062

0 commit comments

Comments
 (0)