feat: allow free form text answers

see #52
This commit is contained in:
James Graham
2021-01-22 17:15:18 +00:00
parent 6dc4bd770f
commit 94b2ee9d70
4 changed files with 59 additions and 2 deletions

View File

@@ -46,9 +46,10 @@ class RelationshipForm(forms.Form):
class DynamicAnswerSetBase(forms.Form):
field_class = forms.ModelChoiceField
field_widget = None
field_required = True
question_model = None
field_widget: typing.Optional[typing.Type[forms.Widget]] = None
question_model: typing.Type[models.Question]
answer_model: typing.Type[models.QuestionChoice]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -72,6 +73,11 @@ class DynamicAnswerSetBase(forms.Form):
initial=initial.get(field_name, None))
self.fields[field_name] = field
if question.allow_free_text:
free_field = forms.CharField(label=f'{question} free text',
required=False)
self.fields[f'{field_name}_free'] = free_field
class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
"""Form for variable person attributes.
@@ -104,6 +110,7 @@ class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
}
question_model = models.PersonQuestion
answer_model = models.PersonQuestionChoice
def save(self, commit=True) -> models.PersonAnswerSet:
# Save Relationship model
@@ -116,6 +123,13 @@ class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
# Save answers to relationship questions
for key, value in self.cleaned_data.items():
if key.startswith('question_') and value:
if key.endswith('_free'):
# Create new answer from free text
value, _ = self.answer_model.objects.get_or_create(
text=value,
question=self.question_model.objects.get(
pk=key.split('_')[1]))
try:
self.instance.question_answers.add(value)
@@ -139,6 +153,7 @@ class RelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
]
question_model = models.RelationshipQuestion
answer_model = models.RelationshipQuestionChoice
def save(self, commit=True) -> models.RelationshipAnswerSet:
# Save Relationship model
@@ -148,6 +163,13 @@ class RelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
# Save answers to relationship questions
for key, value in self.cleaned_data.items():
if key.startswith('question_') and value:
if key.endswith('_free'):
# Create new answer from free text
value, _ = self.answer_model.objects.get_or_create(
text=value,
question=self.question_model.objects.get(
pk=key.split('_')[1]))
try:
self.instance.question_answers.add(value)
@@ -166,6 +188,7 @@ class NetworkFilterForm(DynamicAnswerSetBase):
field_widget = Select2MultipleWidget
field_required = False
question_model = models.RelationshipQuestion
answer_model = models.RelationshipQuestionChoice
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

View File

@@ -0,0 +1,23 @@
# Generated by Django 2.2.10 on 2021-01-20 13:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('people', '0030_user_consent_given'),
]
operations = [
migrations.AddField(
model_name='personquestion',
name='allow_free_text',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='relationshipquestion',
name='allow_free_text',
field=models.BooleanField(default=False),
),
]

View File

@@ -1,2 +1,3 @@
from .person import *
from .question import *
from .relationship import *

View File

@@ -4,6 +4,11 @@ import typing
from django.db import models
from django.utils.text import slugify
__all__ = [
'Question',
'QuestionChoice',
]
class Question(models.Model):
"""Questions from which a survey form can be created."""
@@ -27,6 +32,11 @@ class Question(models.Model):
blank=False,
null=False)
#: Should people be able to add their own answers?
allow_free_text = models.BooleanField(default=False,
blank=False,
null=False)
#: Position of this question in the list
order = models.SmallIntegerField(default=0, blank=False, null=False)