From 6b1f1532c141e2595ca0cf30ff135bf21ca98334 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Tue, 18 Jan 2022 12:18:02 +0100 Subject: [PATCH 4/5] dataviz: move dynamic filters fields creation in mixin (#60547) --- combo/apps/dataviz/forms.py | 76 ++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/combo/apps/dataviz/forms.py b/combo/apps/dataviz/forms.py index 88b549d7..59eb6112 100644 --- a/combo/apps/dataviz/forms.py +++ b/combo/apps/dataviz/forms.py @@ -21,6 +21,7 @@ from django import forms from django.conf import settings from django.db import transaction from django.db.models import Q +from django.db.models.fields import BLANK_CHOICE_DASH from django.template import Context, Template, TemplateSyntaxError, VariableDoesNotExist from django.utils.translation import ugettext_lazy as _ @@ -54,8 +55,7 @@ def trigger_statistics_list_refresh(): transaction.on_commit(spooler.refresh_statistics_list) -class ChartNgForm(forms.ModelForm): - blank_choice = ('', '---------') +class ChartFiltersMixin: time_intervals = ( ('week', _('Week')), ('month', _('Month')), @@ -63,6 +63,35 @@ class ChartNgForm(forms.ModelForm): ('weekday', _('Week day')), ) + def get_filter_fields(self, cell): + fields = OrderedDict() + for filter_ in cell.statistic.filters: + filter_id = filter_['id'] + choices = [(option['id'], option['label']) for option in filter_['options']] + initial = cell.filter_params.get(filter_id, filter_.get('default')) + + required = filter_.get('required', False) + multiple = filter_.get('multiple') + if not required and not multiple: + choices = BLANK_CHOICE_DASH + choices + + field_class = forms.MultipleChoiceField if multiple else forms.ChoiceField + fields[filter_id] = field_class( + label=filter_['label'], choices=choices, required=required, initial=initial + ) + + # extend time interval choices if possible + if 'time_interval' in fields: + choice_ids = {choice_id for choice_id, _ in fields['time_interval'].choices} + if 'day' in choice_ids: + for choice in self.time_intervals: + if choice[0] not in choice_ids: + fields['time_interval'].choices.append(choice) + + return fields + + +class ChartNgForm(ChartFiltersMixin, forms.ModelForm): class Meta: model = ChartNgCell fields = ( @@ -87,16 +116,15 @@ class ChartNgForm(forms.ModelForm): trigger_statistics_list_refresh() super().__init__(*args, **kwargs) - field_ids = list(self._meta.fields) if not self.instance.statistic or self.instance.statistic.service_slug == 'bijoe': - exclude = ( + for field in ( 'time_range', 'time_range_start', 'time_range_end', 'time_range_start_template', 'time_range_end_template', - ) - field_ids = [x for x in field_ids if x not in exclude] + ): + del self.fields[field] stat_field = self.fields['statistic'] if not self.instance.statistic: @@ -107,27 +135,13 @@ class ChartNgForm(forms.ModelForm): Q(available=True) | Q(pk=self.instance.statistic.pk) ) - field_insert_index = field_ids.index('statistic') + 1 - for filter_ in reversed(self.instance.statistic.filters): - filter_id = filter_['id'] - choices = [(option['id'], option['label']) for option in filter_['options']] - initial = self.instance.filter_params.get(filter_id, filter_.get('default')) - - required = filter_.get('required', False) - multiple = filter_.get('multiple') - if not required and not multiple: - choices.insert(0, self.blank_choice) - - field_class = forms.MultipleChoiceField if multiple else forms.ChoiceField - self.fields[filter_id] = field_class( - label=filter_['label'], choices=choices, required=required, initial=initial - ) - field_ids.insert(field_insert_index, filter_id) - - self.fields = OrderedDict((field_id, self.fields[field_id]) for field_id in field_ids) - - if 'time_interval' in self.fields: - self.extend_time_interval_choices() + new_fields = OrderedDict() + for field_name, field in self.fields.items(): + new_fields[field_name] = field + if field_name == 'statistic': + # insert filter fields after statistic field + new_fields.update(self.get_filter_fields(self.instance)) + self.fields = new_fields def save(self, *args, **kwargs): if 'statistic' in self.changed_data: @@ -141,14 +155,6 @@ class ChartNgForm(forms.ModelForm): self.instance.filter_params[filter_['id']] = self.cleaned_data.get(filter_['id']) return super().save(*args, **kwargs) - def extend_time_interval_choices(self): - choice_ids = {choice_id for choice_id, _ in self.fields['time_interval'].choices} - if 'day' not in choice_ids: - return - for choice in self.time_intervals: - if choice[0] not in choice_ids: - self.fields['time_interval'].choices.append(choice) - def clean(self): for template_field in ('time_range_start_template', 'time_range_end_template'): if not self.cleaned_data.get(template_field): -- 2.30.2