|
42 | 42 | # annotations: a list of annotation names that have to be applied to the queryset for the expr to work (optional), |
43 | 43 | Stat = namedtuple( |
44 | 44 | 'Stat', |
45 | | - ['expr', 'filters', 'group_by', 'annotations'], |
46 | | - defaults=[{}, None, []], |
| 45 | + ['expr', 'filters', 'group_by', 'annotations', 'min_value'], |
| 46 | + defaults=[{}, None, [], None], |
47 | 47 | ) |
48 | 48 |
|
49 | 49 |
|
@@ -3008,20 +3008,42 @@ def _get_stat(self, request, queryset, stat, annotations, include_annotations): |
3008 | 3008 | } |
3009 | 3009 |
|
3010 | 3010 | group_by = stat.group_by.replace('.', '__') |
| 3011 | + |
| 3012 | + value = { |
| 3013 | + # The jsonloads/jsondumps is to make sure we can handle different |
| 3014 | + # types as keys, an example is dates. |
| 3015 | + jsonloads(jsondumps(key)): value |
| 3016 | + for key, value in ( |
| 3017 | + queryset |
| 3018 | + .order_by() |
| 3019 | + .exclude(**{group_by: None}) |
| 3020 | + .values(group_by) |
| 3021 | + .annotate(_binder_stat=stat.expr) |
| 3022 | + .values_list(group_by, '_binder_stat') |
| 3023 | + ) |
| 3024 | + } |
| 3025 | + |
| 3026 | + other = 0 |
| 3027 | + if stat.min_value is not None: |
| 3028 | + min_value = stat.min_value * sum(value.values()) |
| 3029 | + new_value = {} |
| 3030 | + |
| 3031 | + others = 0 |
| 3032 | + for key, sub_value in value.items(): |
| 3033 | + if sub_value >= min_value: |
| 3034 | + new_value[key] = sub_value |
| 3035 | + else: |
| 3036 | + other += sub_value |
| 3037 | + others += 1 |
| 3038 | + |
| 3039 | + if others > 1: |
| 3040 | + value = new_value |
| 3041 | + else: |
| 3042 | + other = 0 |
| 3043 | + |
3011 | 3044 | return { |
3012 | | - 'value': { |
3013 | | - # The jsonloads/jsondumps is to make sure we can handle different |
3014 | | - # types as keys, an example is dates. |
3015 | | - jsonloads(jsondumps(key)): value |
3016 | | - for key, value in ( |
3017 | | - queryset |
3018 | | - .order_by() |
3019 | | - .exclude(**{group_by: None}) |
3020 | | - .values(group_by) |
3021 | | - .annotate(_binder_stat=stat.expr) |
3022 | | - .values_list(group_by, '_binder_stat') |
3023 | | - ) |
3024 | | - }, |
| 3045 | + 'value': value, |
| 3046 | + 'other': other, |
3025 | 3047 | 'group_by': stat.group_by, |
3026 | 3048 | 'filters': stat.filters, |
3027 | 3049 | } |
|
0 commit comments