diff --git a/people/forms.py b/people/forms.py index 0d49422..e6c4fe8 100644 --- a/people/forms.py +++ b/people/forms.py @@ -1,7 +1,6 @@ """ Forms for creating / updating models belonging to the 'people' app. """ - from django import forms from . import models @@ -17,3 +16,42 @@ class PersonForm(forms.ModelForm): 'name', 'core_member', ] + + +class RelationshipForm(forms.ModelForm): + """ + Form to allow users to describe a relationship - includes :class:`RelationshipQuestion`s. + + Dynamic fields inspired by https://jacobian.org/2010/feb/28/dynamic-form-generation/ + """ + class Meta: + model = models.Relationship + fields = [ + 'source', + 'target', + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + for question in models.RelationshipQuestion.objects.all(): + # Get choices from model and add default 'not selected' option + choices = question.choices + [['', '---------']] + + field = forms.ChoiceField(label=question, + choices=choices) + self.fields['question_{}'.format(question.pk)] = field + + def save(self, commit=True) -> models.Relationship: + # Save Relationship model + self.instance = super().save(commit=commit) + + if commit: + # Save answers to relationship questions + for key, value in self.cleaned_data.items(): + if key.startswith('question_'): + question_pk = key.split('_')[-1] + answer = models.RelationshipQuestionChoice.objects.get(pk=value) + self.instance.question_answers.add(answer) + + return self.instance diff --git a/people/migrations/0007_relationship_question_answers.py b/people/migrations/0007_relationship_question_answers.py new file mode 100644 index 0000000..bf8e972 --- /dev/null +++ b/people/migrations/0007_relationship_question_answers.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.10 on 2020-02-20 13:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('people', '0006_relationship_questions_order'), + ] + + operations = [ + migrations.AddField( + model_name='relationship', + name='question_answers', + field=models.ManyToManyField(to='people.RelationshipQuestionChoice'), + ), + ] diff --git a/people/models.py b/people/models.py index 180c8b0..ba3cf0f 100644 --- a/people/models.py +++ b/people/models.py @@ -139,5 +139,11 @@ class Relationship(models.Model): on_delete=models.CASCADE, blank=False, null=False) + #: Answers to :class:`RelationshipQuestion`s + question_answers = models.ManyToManyField(RelationshipQuestionChoice) + + def get_absolute_url(self): + return reverse('people:relationship.detail', kwargs={'pk': self.pk}) + def __str__(self) -> str: return f'{self.source} -> {self.target}' diff --git a/people/templates/people/person/detail.html b/people/templates/people/person/detail.html index ad469a6..f12ccdf 100644 --- a/people/templates/people/person/detail.html +++ b/people/templates/people/person/detail.html @@ -14,6 +14,10 @@