Skip to content

Commit

Permalink
Add min_value option to stats
Browse files Browse the repository at this point in the history
  • Loading branch information
daanvdk committed Jun 10, 2024
1 parent be1df65 commit 12e4845
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 15 deletions.
52 changes: 37 additions & 15 deletions binder/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
# annotations: a list of annotation names that have to be applied to the queryset for the expr to work (optional),
Stat = namedtuple(
'Stat',
['expr', 'filters', 'group_by', 'annotations'],
defaults=[{}, None, []],
['expr', 'filters', 'group_by', 'annotations', 'min_value'],
defaults=[{}, None, [], None],
)


Expand Down Expand Up @@ -3008,20 +3008,42 @@ def _get_stat(self, request, queryset, stat, annotations, include_annotations):
}

group_by = stat.group_by.replace('.', '__')

value = {
# The jsonloads/jsondumps is to make sure we can handle different
# types as keys, an example is dates.
jsonloads(jsondumps(key)): value
for key, value in (
queryset
.order_by()
.exclude(**{group_by: None})
.values(group_by)
.annotate(_binder_stat=stat.expr)
.values_list(group_by, '_binder_stat')
)
}

other = 0
if stat.min_value is not None:
min_value = stat.min_value * sum(value.values())
new_value = {}

others = 0
for key, sub_value in value.items():
if sub_value >= min_value:
new_value[key] = sub_value
else:
other += sub_value
others += 1

if others > 1:
value = new_value
else:
other = 0

return {
'value': {
# The jsonloads/jsondumps is to make sure we can handle different
# types as keys, an example is dates.
jsonloads(jsondumps(key)): value
for key, value in (
queryset
.order_by()
.exclude(**{group_by: None})
.values(group_by)
.annotate(_binder_stat=stat.expr)
.values_list(group_by, '_binder_stat')
)
},
'value': value,
'other': other,
'group_by': stat.group_by,
'filters': stat.filters,
}
Expand Down
13 changes: 13 additions & 0 deletions tests/test_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def test_animals_by_zoo(self):
self.assertEqual(res, {
'by_zoo': {
'value': {'Zoo 1': 1, 'Zoo 2': 2},
'other': 0,
'filters': {},
'group_by': 'zoo.name',
},
Expand All @@ -71,6 +72,7 @@ def test_stats_filtered(self):
},
'by_zoo': {
'value': {'Zoo 1': 1},
'other': 0,
'filters': {},
'group_by': 'zoo.name',
},
Expand All @@ -83,3 +85,14 @@ def test_stat_not_found(self):
'message': 'unknown stat: does_not_exist',
'debug': ANY(),
})

def test_animals_by_zoo(self):
res = self.get_stats('by_zoo')
self.assertEqual(res, {
'by_zoo': {
'value': {'Zoo 1': 1, 'Zoo 2': 2},
'other': 0,
'filters': {},
'group_by': 'zoo.name',
},
})

0 comments on commit 12e4845

Please sign in to comment.