mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 03:17:07 +00:00
feat: add organisation questions to update view
This commit is contained in:
@@ -57,7 +57,7 @@ class DynamicAnswerSetBase(forms.Form):
|
|||||||
field = field_class(label=question,
|
field = field_class(label=question,
|
||||||
queryset=question.answers,
|
queryset=question.answers,
|
||||||
widget=field_widget,
|
widget=field_widget,
|
||||||
required=self.field_required,
|
required=self.field_required and not question.allow_free_text,
|
||||||
initial=initial.get(field_name, None))
|
initial=initial.get(field_name, None))
|
||||||
self.fields[field_name] = field
|
self.fields[field_name] = field
|
||||||
|
|
||||||
@@ -67,6 +67,48 @@ class DynamicAnswerSetBase(forms.Form):
|
|||||||
self.fields[f'{field_name}_free'] = free_field
|
self.fields[f'{field_name}_free'] = free_field
|
||||||
|
|
||||||
|
|
||||||
|
class OrganisationAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
||||||
|
"""Form for variable organisation attributes.
|
||||||
|
|
||||||
|
Dynamic fields inspired by https://jacobian.org/2010/feb/28/dynamic-form-generation/
|
||||||
|
"""
|
||||||
|
class Meta:
|
||||||
|
model = models.OrganisationAnswerSet
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
question_model = models.OrganisationQuestion
|
||||||
|
answer_model = models.OrganisationQuestionChoice
|
||||||
|
|
||||||
|
def save(self, commit=True) -> models.OrganisationAnswerSet:
|
||||||
|
# Save model
|
||||||
|
self.instance = super().save(commit=False)
|
||||||
|
self.instance.organisation_id = self.initial['organisation_id']
|
||||||
|
if commit:
|
||||||
|
self.instance.save()
|
||||||
|
# Need to call same_m2m manually since we use commit=False above
|
||||||
|
self.save_m2m()
|
||||||
|
|
||||||
|
if commit:
|
||||||
|
# Save answers to 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)
|
||||||
|
|
||||||
|
except TypeError:
|
||||||
|
# Value is a QuerySet - multiple choice question
|
||||||
|
self.instance.question_answers.add(*value.all())
|
||||||
|
|
||||||
|
return self.instance
|
||||||
|
|
||||||
|
|
||||||
class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
||||||
"""Form for variable person attributes.
|
"""Form for variable person attributes.
|
||||||
|
|
||||||
@@ -101,7 +143,7 @@ class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
|||||||
answer_model = models.PersonQuestionChoice
|
answer_model = models.PersonQuestionChoice
|
||||||
|
|
||||||
def save(self, commit=True) -> models.PersonAnswerSet:
|
def save(self, commit=True) -> models.PersonAnswerSet:
|
||||||
# Save Relationship model
|
# Save model
|
||||||
self.instance = super().save(commit=False)
|
self.instance = super().save(commit=False)
|
||||||
self.instance.person_id = self.initial['person_id']
|
self.instance.person_id = self.initial['person_id']
|
||||||
if commit:
|
if commit:
|
||||||
@@ -110,7 +152,7 @@ class PersonAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
|||||||
self.save_m2m()
|
self.save_m2m()
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
# Save answers to relationship questions
|
# Save answers to 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'):
|
if key.endswith('_free'):
|
||||||
@@ -146,11 +188,11 @@ class RelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
|||||||
answer_model = models.RelationshipQuestionChoice
|
answer_model = models.RelationshipQuestionChoice
|
||||||
|
|
||||||
def save(self, commit=True) -> models.RelationshipAnswerSet:
|
def save(self, commit=True) -> models.RelationshipAnswerSet:
|
||||||
# Save Relationship model
|
# Save model
|
||||||
self.instance = super().save(commit=commit)
|
self.instance = super().save(commit=commit)
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
# Save answers to relationship questions
|
# Save answers to 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'):
|
if key.endswith('_free'):
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
{% include 'people/person/includes/answer_set_full.html' %}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
<div id="map" style="height: 800px; width: 100%"></div>
|
<div id="map" style="height: 800px; width: 100%"></div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|||||||
@@ -33,10 +33,7 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
{% load bootstrap4 %}
|
{% load bootstrap4 %}
|
||||||
{% bootstrap_form form exclude='latitude,longitude' %}
|
{% bootstrap_form form %}
|
||||||
|
|
||||||
{% bootstrap_field form.latitude %}
|
|
||||||
{% bootstrap_field form.longitude %}
|
|
||||||
|
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
<button class="btn btn-success" type="submit">Submit</button>
|
<button class="btn btn-success" type="submit">Submit</button>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import typing
|
import typing
|
||||||
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.utils import timezone
|
||||||
from django.views.generic import CreateView, DetailView, ListView, UpdateView
|
from django.views.generic import CreateView, DetailView, ListView, UpdateView
|
||||||
|
|
||||||
from people import forms, models
|
from people import forms, models
|
||||||
@@ -30,6 +31,7 @@ class OrganisationDetailView(LoginRequiredMixin, DetailView):
|
|||||||
"""Add map marker to context."""
|
"""Add map marker to context."""
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
context['answer_set'] = self.object.current_answers
|
||||||
context['map_markers'] = [{
|
context['map_markers'] = [{
|
||||||
'name': self.object.name,
|
'name': self.object.name,
|
||||||
'lat': self.object.latitude,
|
'lat': self.object.latitude,
|
||||||
@@ -44,7 +46,7 @@ class OrganisationUpdateView(LoginRequiredMixin, UpdateView):
|
|||||||
model = models.Organisation
|
model = models.Organisation
|
||||||
context_object_name = 'organisation'
|
context_object_name = 'organisation'
|
||||||
template_name = 'people/organisation/update.html'
|
template_name = 'people/organisation/update.html'
|
||||||
form_class = forms.OrganisationForm
|
form_class = forms.OrganisationAnswerSetForm
|
||||||
|
|
||||||
def get_context_data(self,
|
def get_context_data(self,
|
||||||
**kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
|
**kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
|
||||||
@@ -58,3 +60,37 @@ class OrganisationUpdateView(LoginRequiredMixin, UpdateView):
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
def get_initial(self) -> typing.Dict[str, typing.Any]:
|
||||||
|
try:
|
||||||
|
previous_answers = self.object.current_answers.as_dict()
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
previous_answers = {}
|
||||||
|
|
||||||
|
previous_answers.update({
|
||||||
|
'organisation_id': self.object.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
return previous_answers
|
||||||
|
|
||||||
|
def get_form_kwargs(self) -> typing.Dict[str, typing.Any]:
|
||||||
|
"""Remove instance from form kwargs as it's an Organisation, but expects an OrganisationAnswerSet."""
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs.pop('instance')
|
||||||
|
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
"""Mark any previous answer sets as replaced."""
|
||||||
|
response = super().form_valid(form)
|
||||||
|
now_date = timezone.now().date()
|
||||||
|
|
||||||
|
# Saving the form made self.object an OrganisationAnswerSet - so go up, then back down
|
||||||
|
# Shouldn't be more than one after initial updates after migration
|
||||||
|
for answer_set in self.object.organisation.answer_sets.exclude(
|
||||||
|
pk=self.object.pk):
|
||||||
|
answer_set.replaced_timestamp = now_date
|
||||||
|
answer_set.save()
|
||||||
|
|
||||||
|
return response
|
||||||
|
|||||||
Reference in New Issue
Block a user