From 2664ff6e8375b8b1139a4add72d7692b0842dbcc Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 26 Mar 2021 11:36:19 +0000 Subject: [PATCH] refactor: allow question prefix on dynamic forms Setup to support multiple network filters See #54 --- people/forms.py | 29 ++++++++++++++++++++++++----- people/views/network.py | 6 +++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/people/forms.py b/people/forms.py index ae0a0e9..61cf2ee 100644 --- a/people/forms.py +++ b/people/forms.py @@ -41,6 +41,7 @@ class DynamicAnswerSetBase(forms.Form): field_widget: typing.Optional[typing.Type[forms.Widget]] = None question_model: typing.Type[models.Question] answer_model: typing.Type[models.QuestionChoice] + question_prefix: str = '' def __init__(self, *args, as_filters: bool = False, **kwargs): super().__init__(*args, **kwargs) @@ -64,7 +65,7 @@ class DynamicAnswerSetBase(forms.Form): field_class = forms.ModelMultipleChoiceField field_widget = Select2MultipleWidget - field_name = f'question_{question.pk}' + field_name = f'{self.question_prefix}question_{question.pk}' # If being used as a filter - do we have alternate text? field_label = question.text @@ -310,15 +311,33 @@ class OrganisationRelationshipAnswerSetForm(forms.ModelForm, return self.instance -class NetworkFilterForm(DynamicAnswerSetBase): - """ - Form to provide filtering on the network view. - """ +class NetworkRelationshipFilterForm(DynamicAnswerSetBase): + """Form to provide filtering on the network view.""" field_class = forms.ModelMultipleChoiceField field_widget = Select2MultipleWidget field_required = False question_model = models.RelationshipQuestion answer_model = models.RelationshipQuestionChoice + question_prefix = 'relationship_' + + def __init__(self, *args, **kwargs): + super().__init__(*args, as_filters=True, **kwargs) + + # Add date field to select relationships at a particular point in time + self.fields['date'] = forms.DateField( + required=False, + widget=DatePickerInput(format='%Y-%m-%d'), + help_text='Show relationships as they were on this date') + + +class NetworkPersonFilterForm(DynamicAnswerSetBase): + """Form to provide filtering on the network view.""" + field_class = forms.ModelMultipleChoiceField + field_widget = Select2MultipleWidget + field_required = False + question_model = models.PersonQuestion + answer_model = models.PersonQuestionChoice + question_prefix = 'person_' def __init__(self, *args, **kwargs): super().__init__(*args, as_filters=True, **kwargs) diff --git a/people/views/network.py b/people/views/network.py index d2a483e..2cd0aec 100644 --- a/people/views/network.py +++ b/people/views/network.py @@ -20,7 +20,7 @@ class NetworkView(LoginRequiredMixin, FormView): View to display relationship network. """ template_name = 'people/network.html' - form_class = forms.NetworkFilterForm + form_class = forms.NetworkRelationshipFilterForm def get_form_kwargs(self): """ @@ -42,7 +42,7 @@ class NetworkView(LoginRequiredMixin, FormView): Add filtered QuerySets of :class:`Person` and :class:`Relationship` to the context. """ context = super().get_context_data(**kwargs) - form: forms.NetworkFilterForm = context['form'] + form: forms.NetworkRelationshipFilterForm = context['form'] if not form.is_valid(): return context @@ -65,7 +65,7 @@ class NetworkView(LoginRequiredMixin, FormView): # Filter answers to relationship questions for field, values in form.cleaned_data.items(): - if field.startswith('question_') and values: + if field.startswith(f'{form.question_prefix}question_') and values: relationship_answerset_set = relationship_answerset_set.filter( question_answers__in=values)