mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 11:27:09 +00:00
@@ -46,9 +46,10 @@ class RelationshipForm(forms.Form):
|
|||||||
|
|
||||||
class DynamicAnswerSetBase(forms.Form):
|
class DynamicAnswerSetBase(forms.Form):
|
||||||
field_class = forms.ModelChoiceField
|
field_class = forms.ModelChoiceField
|
||||||
field_widget = None
|
|
||||||
field_required = True
|
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):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@@ -72,6 +73,11 @@ class DynamicAnswerSetBase(forms.Form):
|
|||||||
initial=initial.get(field_name, None))
|
initial=initial.get(field_name, None))
|
||||||
self.fields[field_name] = field
|
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):
|
class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
||||||
"""Form for variable person attributes.
|
"""Form for variable person attributes.
|
||||||
@@ -104,6 +110,7 @@ class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
question_model = models.PersonQuestion
|
question_model = models.PersonQuestion
|
||||||
|
answer_model = models.PersonQuestionChoice
|
||||||
|
|
||||||
def save(self, commit=True) -> models.PersonAnswerSet:
|
def save(self, commit=True) -> models.PersonAnswerSet:
|
||||||
# Save Relationship model
|
# Save Relationship model
|
||||||
@@ -116,6 +123,13 @@ class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
|||||||
# Save answers to relationship questions
|
# Save answers to relationship questions
|
||||||
for key, value in self.cleaned_data.items():
|
for key, value in self.cleaned_data.items():
|
||||||
if key.startswith('question_') and value:
|
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:
|
try:
|
||||||
self.instance.question_answers.add(value)
|
self.instance.question_answers.add(value)
|
||||||
|
|
||||||
@@ -139,6 +153,7 @@ class RelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
question_model = models.RelationshipQuestion
|
question_model = models.RelationshipQuestion
|
||||||
|
answer_model = models.RelationshipQuestionChoice
|
||||||
|
|
||||||
def save(self, commit=True) -> models.RelationshipAnswerSet:
|
def save(self, commit=True) -> models.RelationshipAnswerSet:
|
||||||
# Save Relationship model
|
# Save Relationship model
|
||||||
@@ -148,6 +163,13 @@ class RelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
|||||||
# Save answers to relationship questions
|
# Save answers to relationship questions
|
||||||
for key, value in self.cleaned_data.items():
|
for key, value in self.cleaned_data.items():
|
||||||
if key.startswith('question_') and value:
|
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:
|
try:
|
||||||
self.instance.question_answers.add(value)
|
self.instance.question_answers.add(value)
|
||||||
|
|
||||||
@@ -166,6 +188,7 @@ class NetworkFilterForm(DynamicAnswerSetBase):
|
|||||||
field_widget = Select2MultipleWidget
|
field_widget = Select2MultipleWidget
|
||||||
field_required = False
|
field_required = False
|
||||||
question_model = models.RelationshipQuestion
|
question_model = models.RelationshipQuestion
|
||||||
|
answer_model = models.RelationshipQuestionChoice
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|||||||
23
people/migrations/0031_question_allow_free_text.py
Normal file
23
people/migrations/0031_question_allow_free_text.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
from .person import *
|
from .person import *
|
||||||
|
from .question import *
|
||||||
from .relationship import *
|
from .relationship import *
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ import typing
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'Question',
|
||||||
|
'QuestionChoice',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Question(models.Model):
|
class Question(models.Model):
|
||||||
"""Questions from which a survey form can be created."""
|
"""Questions from which a survey form can be created."""
|
||||||
@@ -27,6 +32,11 @@ class Question(models.Model):
|
|||||||
blank=False,
|
blank=False,
|
||||||
null=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
|
#: Position of this question in the list
|
||||||
order = models.SmallIntegerField(default=0, blank=False, null=False)
|
order = models.SmallIntegerField(default=0, blank=False, null=False)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user