mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 03:17:07 +00:00
@@ -85,3 +85,19 @@ class RelationshipQuestionAdmin(admin.ModelAdmin):
|
||||
@admin.register(models.Relationship)
|
||||
class RelationshipAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class OrganisationRelationshipQuestionChoiceInline(admin.TabularInline):
|
||||
model = models.OrganisationRelationshipQuestionChoice
|
||||
|
||||
|
||||
@admin.register(models.OrganisationRelationshipQuestion)
|
||||
class OrganisationRelationshipQuestionAdmin(admin.ModelAdmin):
|
||||
inlines = [
|
||||
OrganisationRelationshipQuestionChoiceInline,
|
||||
]
|
||||
|
||||
|
||||
@admin.register(models.OrganisationRelationship)
|
||||
class OrganisationRelationshipAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
@@ -239,6 +239,48 @@ class RelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
||||
return self.instance
|
||||
|
||||
|
||||
class OrganisationRelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
|
||||
"""Form to allow users to describe a relationship with an organisation.
|
||||
|
||||
Dynamic fields inspired by https://jacobian.org/2010/feb/28/dynamic-form-generation/
|
||||
"""
|
||||
class Meta:
|
||||
model = models.OrganisationRelationshipAnswerSet
|
||||
fields = [
|
||||
'relationship',
|
||||
]
|
||||
widgets = {
|
||||
'relationship': forms.HiddenInput,
|
||||
}
|
||||
|
||||
question_model = models.OrganisationRelationshipQuestion
|
||||
answer_model = models.OrganisationRelationshipQuestionChoice
|
||||
|
||||
def save(self, commit=True) -> models.OrganisationRelationshipAnswerSet:
|
||||
# Save model
|
||||
self.instance = super().save(commit=commit)
|
||||
|
||||
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 NetworkFilterForm(DynamicAnswerSetBase):
|
||||
"""
|
||||
Form to provide filtering on the network view.
|
||||
|
||||
76
people/migrations/0039_add_organisation_relationship.py
Normal file
76
people/migrations/0039_add_organisation_relationship.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# Generated by Django 2.2.10 on 2021-03-02 08:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('people', '0038_project_started_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='OrganisationRelationship',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(auto_now_add=True)),
|
||||
('expired', models.DateTimeField(blank=True, null=True)),
|
||||
('source', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organisation_relationships_as_source', to='people.Person')),
|
||||
('target', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organisation_relationships_as_target', to='people.Organisation')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OrganisationRelationshipQuestion',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('version', models.PositiveSmallIntegerField(default=1)),
|
||||
('text', models.CharField(max_length=255)),
|
||||
('filter_text', models.CharField(blank=True, help_text='Text to be displayed in network filters - 3rd person', max_length=255)),
|
||||
('answer_is_public', models.BooleanField(default=True, help_text='Should answers to this question be considered public?')),
|
||||
('is_multiple_choice', models.BooleanField(default=False)),
|
||||
('allow_free_text', models.BooleanField(default=False)),
|
||||
('order', models.SmallIntegerField(default=0)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['order', 'text'],
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OrganisationRelationshipQuestionChoice',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('text', models.CharField(max_length=255)),
|
||||
('order', models.SmallIntegerField(default=0)),
|
||||
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='people.OrganisationRelationshipQuestion')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['question__order', 'order', 'text'],
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OrganisationRelationshipAnswerSet',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('timestamp', models.DateTimeField(auto_now_add=True)),
|
||||
('replaced_timestamp', models.DateTimeField(blank=True, editable=False, null=True)),
|
||||
('question_answers', models.ManyToManyField(to='people.OrganisationRelationshipQuestionChoice')),
|
||||
('relationship', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answer_sets', to='people.OrganisationRelationship')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['timestamp'],
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='organisationrelationshipquestionchoice',
|
||||
constraint=models.UniqueConstraint(fields=('question', 'text'), name='unique_question_answer'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='organisationrelationship',
|
||||
constraint=models.UniqueConstraint(fields=('source', 'target'), name='unique_relationship'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 2.2.10 on 2021-03-02 08:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('people', '0039_add_organisation_relationship'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='person',
|
||||
name='organisation_relationship_targets',
|
||||
field=models.ManyToManyField(related_name='relationship_sources', through='people.OrganisationRelationship', to='people.Organisation'),
|
||||
),
|
||||
]
|
||||
@@ -226,6 +226,13 @@ class Person(models.Model):
|
||||
through_fields=('source', 'target'),
|
||||
symmetrical=False)
|
||||
|
||||
#: Organisations with whom this person has relationship - via intermediate :class:`OrganisationRelationship` model
|
||||
organisation_relationship_targets = models.ManyToManyField(
|
||||
Organisation,
|
||||
related_name='relationship_sources',
|
||||
through='OrganisationRelationship',
|
||||
through_fields=('source', 'target'))
|
||||
|
||||
@property
|
||||
def relationships(self):
|
||||
return self.relationships_as_source.all().union(
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
Models describing relationships between people.
|
||||
"""
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
|
||||
from .person import Person
|
||||
from .person import Organisation, Person
|
||||
from .question import AnswerSet, Question, QuestionChoice
|
||||
|
||||
__all__ = [
|
||||
@@ -14,6 +13,10 @@ __all__ = [
|
||||
'RelationshipQuestionChoice',
|
||||
'RelationshipAnswerSet',
|
||||
'Relationship',
|
||||
'OrganisationRelationshipQuestion',
|
||||
'OrganisationRelationshipQuestionChoice',
|
||||
'OrganisationRelationshipAnswerSet',
|
||||
'OrganisationRelationship',
|
||||
]
|
||||
|
||||
|
||||
@@ -32,24 +35,10 @@ class RelationshipQuestionChoice(QuestionChoice):
|
||||
null=False)
|
||||
|
||||
|
||||
# class ExternalPerson(models.Model):
|
||||
# """Model representing a person external to the project.
|
||||
|
||||
# These will never need to be linked to a :class:`User` as they
|
||||
# will never log in to the system.
|
||||
# """
|
||||
# name = models.CharField(max_length=255,
|
||||
# blank=False, null=False)
|
||||
|
||||
# def __str__(self) -> str:
|
||||
# return self.name
|
||||
|
||||
|
||||
class Relationship(models.Model):
|
||||
"""
|
||||
A directional relationship between two people allowing linked questions.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=['source', 'target'],
|
||||
@@ -57,9 +46,11 @@ class Relationship(models.Model):
|
||||
]
|
||||
|
||||
#: Person reporting the relationship
|
||||
source = models.ForeignKey(Person, related_name='relationships_as_source',
|
||||
source = models.ForeignKey(Person,
|
||||
related_name='relationships_as_source',
|
||||
on_delete=models.CASCADE,
|
||||
blank=False, null=False)
|
||||
blank=False,
|
||||
null=False)
|
||||
|
||||
#: Person with whom the relationship is reported
|
||||
target = models.ForeignKey(Person,
|
||||
@@ -67,15 +58,6 @@ class Relationship(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
blank=False,
|
||||
null=False)
|
||||
# blank=True,
|
||||
# null=True)
|
||||
|
||||
# target_external_person = models.ForeignKey(
|
||||
# ExternalPerson,
|
||||
# related_name='relationships_as_target',
|
||||
# on_delete=models.CASCADE,
|
||||
# blank=True,
|
||||
# null=True)
|
||||
|
||||
#: When was this relationship defined?
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
@@ -100,8 +82,7 @@ class Relationship(models.Model):
|
||||
|
||||
@raise Relationship.DoesNotExist: When the reverse relationship is not known
|
||||
"""
|
||||
return type(self).objects.get(source=self.target,
|
||||
target=self.source)
|
||||
return type(self).objects.get(source=self.target, target=self.source)
|
||||
|
||||
|
||||
class RelationshipAnswerSet(AnswerSet):
|
||||
@@ -119,3 +100,78 @@ class RelationshipAnswerSet(AnswerSet):
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.relationship.get_absolute_url()
|
||||
|
||||
|
||||
class OrganisationRelationshipQuestion(Question):
|
||||
"""Question which may be asked about an :class:`OrganisationRelationship`."""
|
||||
|
||||
|
||||
class OrganisationRelationshipQuestionChoice(QuestionChoice):
|
||||
"""Allowed answer to a :class:`OrganisationRelationshipQuestion`."""
|
||||
|
||||
#: Question to which this answer belongs
|
||||
question = models.ForeignKey(OrganisationRelationshipQuestion,
|
||||
related_name='answers',
|
||||
on_delete=models.CASCADE,
|
||||
blank=False,
|
||||
null=False)
|
||||
|
||||
|
||||
class OrganisationRelationship(models.Model):
|
||||
"""A directional relationship between a person and an organisation with linked questions."""
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=['source', 'target'],
|
||||
name='unique_relationship'),
|
||||
]
|
||||
|
||||
#: Person reporting the relationship
|
||||
source = models.ForeignKey(
|
||||
Person,
|
||||
related_name='organisation_relationships_as_source',
|
||||
on_delete=models.CASCADE,
|
||||
blank=False,
|
||||
null=False)
|
||||
|
||||
#: Organisation with which the relationship is reported
|
||||
target = models.ForeignKey(
|
||||
Organisation,
|
||||
related_name='organisation_relationships_as_target',
|
||||
on_delete=models.CASCADE,
|
||||
blank=False,
|
||||
null=False)
|
||||
|
||||
#: When was this relationship defined?
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
#: When was this marked as expired? Default None means it has not expired
|
||||
expired = models.DateTimeField(blank=True, null=True)
|
||||
|
||||
@property
|
||||
def current_answers(self) -> 'OrganisationRelationshipAnswerSet':
|
||||
return self.answer_sets.last()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('people:organisation.relationship.detail',
|
||||
kwargs={'pk': self.pk})
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.source} -> {self.target}'
|
||||
|
||||
|
||||
class OrganisationRelationshipAnswerSet(AnswerSet):
|
||||
"""The answers to the organisation relationship questions at a particular point in time."""
|
||||
|
||||
#: OrganisationRelationship to which this answer set belongs
|
||||
relationship = models.ForeignKey(OrganisationRelationship,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='answer_sets',
|
||||
blank=False,
|
||||
null=False)
|
||||
|
||||
#: Answers to :class:`OrganisationRelationshipQuestion`s
|
||||
question_answers = models.ManyToManyField(
|
||||
OrganisationRelationshipQuestionChoice)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.relationship.get_absolute_url()
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'people:person.list' %}">People</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'people:person.detail' pk=relationship.source.pk %}">{{ relationship.source }}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ relationship.target }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<h1>Organisation Relationship</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row align-content-center align-items-center">
|
||||
<div class="col-md-5 text-center">
|
||||
<h2>Source</h2>
|
||||
<p>{{ relationship.source }}</p>
|
||||
|
||||
<a class="btn btn-sm btn-info"
|
||||
href="{% url 'people:person.detail' pk=relationship.source.pk %}">Profile</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2 text-center"></div>
|
||||
|
||||
<div class="col-md-5 text-center">
|
||||
<h2>Target</h2>
|
||||
<p>{{ relationship.target }}</p>
|
||||
|
||||
<a class="btn btn-sm btn-info"
|
||||
href="{% url 'people:organisation.detail' pk=relationship.target.pk %}">Profile</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<a class="btn btn-success"
|
||||
href="{% url 'people:organisation.relationship.update' relationship_pk=relationship.pk %}">Update</a>
|
||||
|
||||
{% with relationship.current_answers as answer_set %}
|
||||
<table class="table table-borderless">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Question</th>
|
||||
<th>Answer</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for answer in answer_set.question_answers.all %}
|
||||
<tr>
|
||||
<td>{{ answer.question }}</td>
|
||||
<td>{{ answer }}</td>
|
||||
</tr>
|
||||
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td>No records</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Last updated: {{ answer_set.timestamp }}
|
||||
{% endwith %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -28,6 +28,19 @@
|
||||
<td>
|
||||
<a class="btn btn-sm btn-info"
|
||||
href="{% url 'people:organisation.detail' pk=organisation.pk %}">Details</a>
|
||||
|
||||
{% if organisation.pk in existing_relationships %}
|
||||
<a class="btn btn-sm btn-warning"
|
||||
style="width: 10rem"
|
||||
href="{% url 'people:organisation.relationship.create' organisation_pk=organisation.pk %}">Update Relationship
|
||||
</a>
|
||||
|
||||
{% else %}
|
||||
<a class="btn btn-sm btn-success"
|
||||
style="width: 10rem"
|
||||
href="{% url 'people:organisation.relationship.create' organisation_pk=organisation.pk %}">New Relationship
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ from . import views
|
||||
app_name = 'people'
|
||||
|
||||
urlpatterns = [
|
||||
####################
|
||||
# Organisation views
|
||||
path('organisations/create',
|
||||
views.organisation.OrganisationCreateView.as_view(),
|
||||
name='organisation.create'),
|
||||
@@ -22,6 +24,8 @@ urlpatterns = [
|
||||
views.organisation.OrganisationUpdateView.as_view(),
|
||||
name='organisation.update'),
|
||||
|
||||
##############
|
||||
# Person views
|
||||
path('profile/',
|
||||
views.person.ProfileView.as_view(),
|
||||
name='person.profile'),
|
||||
@@ -42,6 +46,8 @@ urlpatterns = [
|
||||
views.person.PersonUpdateView.as_view(),
|
||||
name='person.update'),
|
||||
|
||||
####################
|
||||
# Relationship views
|
||||
path('people/<int:person_pk>/relationships/create',
|
||||
views.relationship.RelationshipCreateView.as_view(),
|
||||
name='person.relationship.create'),
|
||||
@@ -54,6 +60,22 @@ urlpatterns = [
|
||||
views.relationship.RelationshipUpdateView.as_view(),
|
||||
name='relationship.update'),
|
||||
|
||||
################################
|
||||
# OrganisationRelationship views
|
||||
path('organisations/<int:organisation_pk>/relationships/create',
|
||||
views.relationship.OrganisationRelationshipCreateView.as_view(),
|
||||
name='organisation.relationship.create'),
|
||||
|
||||
path('organisation-relationships/<int:pk>',
|
||||
views.relationship.OrganisationRelationshipDetailView.as_view(),
|
||||
name='organisation.relationship.detail'),
|
||||
|
||||
path('organisation-relationships/<int:relationship_pk>/update',
|
||||
views.relationship.OrganisationRelationshipUpdateView.as_view(),
|
||||
name='organisation.relationship.update'),
|
||||
|
||||
############
|
||||
# Data views
|
||||
path('map',
|
||||
views.person.PersonMapView.as_view(),
|
||||
name='person.map'),
|
||||
|
||||
@@ -19,6 +19,16 @@ class OrganisationListView(LoginRequiredMixin, ListView):
|
||||
model = models.Organisation
|
||||
template_name = 'people/organisation/list.html'
|
||||
|
||||
def get_context_data(self,
|
||||
**kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context['existing_relationships'] = set(
|
||||
self.request.user.person.organisation_relationship_targets.
|
||||
values_list('pk', flat=True))
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class OrganisationDetailView(LoginRequiredMixin, DetailView):
|
||||
"""View displaying details of a :class:`Organisation`."""
|
||||
|
||||
@@ -24,7 +24,8 @@ class RelationshipCreateView(LoginRequiredMixin, RedirectView):
|
||||
|
||||
Redirects to a form containing the :class:`RelationshipQuestion`s.
|
||||
"""
|
||||
def get_redirect_url(self, *args: typing.Any, **kwargs: typing.Any) -> typing.Optional[str]:
|
||||
def get_redirect_url(self, *args: typing.Any,
|
||||
**kwargs: typing.Any) -> typing.Optional[str]:
|
||||
target = models.Person.objects.get(pk=self.kwargs.get('person_pk'))
|
||||
relationship, _ = models.Relationship.objects.get_or_create(
|
||||
source=self.request.user.person, target=target)
|
||||
@@ -96,3 +97,94 @@ class RelationshipUpdateView(permissions.UserIsLinkedPersonMixin, CreateView):
|
||||
answer_set.save()
|
||||
|
||||
return response
|
||||
|
||||
|
||||
class OrganisationRelationshipDetailView(permissions.UserIsLinkedPersonMixin,
|
||||
DetailView):
|
||||
"""View displaying details of an :class:`OrganisationRelationship`."""
|
||||
model = models.OrganisationRelationship
|
||||
template_name = 'people/organisation-relationship/detail.html'
|
||||
related_person_field = 'source'
|
||||
context_object_name = 'relationship'
|
||||
|
||||
|
||||
class OrganisationRelationshipCreateView(LoginRequiredMixin, RedirectView):
|
||||
"""View for creating a :class:`OrganisationRelationship`.
|
||||
|
||||
Redirects to a form containing the :class:`OrganisationRelationshipQuestion`s.
|
||||
"""
|
||||
def get_redirect_url(self, *args: typing.Any,
|
||||
**kwargs: typing.Any) -> typing.Optional[str]:
|
||||
target = models.Organisation.objects.get(
|
||||
pk=self.kwargs.get('organisation_pk'))
|
||||
relationship, _ = models.OrganisationRelationship.objects.get_or_create(
|
||||
source=self.request.user.person, target=target)
|
||||
|
||||
return reverse('people:organisation.relationship.update',
|
||||
kwargs={'relationship_pk': relationship.pk})
|
||||
|
||||
|
||||
class OrganisationRelationshipUpdateView(permissions.UserIsLinkedPersonMixin,
|
||||
CreateView):
|
||||
"""
|
||||
View for updating the details of a Organisationrelationship.
|
||||
|
||||
Creates a new :class:`OrganisationRelationshipAnswerSet` for the :class:`OrganisationRelationship`.
|
||||
Displays / processes a form containing the :class:`OrganisationRelationshipQuestion`s.
|
||||
"""
|
||||
model = models.OrganisationRelationshipAnswerSet
|
||||
template_name = 'people/relationship/update.html'
|
||||
form_class = forms.OrganisationRelationshipAnswerSetForm
|
||||
|
||||
def get_test_person(self) -> models.Person:
|
||||
"""
|
||||
Get the person instance which should be used for access control checks.
|
||||
"""
|
||||
relationship = models.OrganisationRelationship.objects.get(
|
||||
pk=self.kwargs.get('relationship_pk'))
|
||||
|
||||
return relationship.source
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.relationship = models.OrganisationRelationship.objects.get(
|
||||
pk=self.kwargs.get('relationship_pk'))
|
||||
self.person = self.relationship.source
|
||||
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.relationship = models.OrganisationRelationship.objects.get(
|
||||
pk=self.kwargs.get('relationship_pk'))
|
||||
self.person = self.relationship.source
|
||||
|
||||
return super().post(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context['person'] = self.person
|
||||
context['relationship'] = self.relationship
|
||||
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
initial = super().get_initial()
|
||||
|
||||
initial['relationship'] = self.relationship
|
||||
|
||||
return initial
|
||||
|
||||
def form_valid(self, form):
|
||||
"""
|
||||
Mark any previous answer sets as replaced.
|
||||
"""
|
||||
response = super().form_valid(form)
|
||||
now_date = timezone.now().date()
|
||||
|
||||
# Shouldn't be more than one after initial updates after migration
|
||||
for answer_set in self.relationship.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