diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6305521
--- /dev/null
+++ b/README.md
@@ -0,0 +1,19 @@
+# BRECcIA-Mapper (provisional name)
+
+The canonical source for this project is hosted on [GitHub](https://github.com/Southampton-RSG/breccia-mapper),
+please log any issues there.
+
+BRECcIA-Mapper is a web app to collect and explore data about the relationships between researchers and their stakeholders on large-scale, multi-site research projects.
+
+TODO motivations, usage, license
+
+## Technology
+
+This project is written in Python using the popular [Django](https://www.djangoproject.com/) framework.
+
+An [Ansible](https://www.ansible.com/) playbook is provided which is designed for deployment on RHEL7 or CentOS7 Linux systems. This installs and configures:
+- MySQL
+- Nginx
+- Django + BRECcIA-Mapper
+
+TODO deployment instructions
\ No newline at end of file
diff --git a/breccia_mapper/settings.py b/breccia_mapper/settings.py
index 22aa5ee..20a0aa8 100644
--- a/breccia_mapper/settings.py
+++ b/breccia_mapper/settings.py
@@ -134,6 +134,16 @@ DBBACKUP_STORAGE_OPTIONS = {
}
+# Django REST Framework
+# https://www.django-rest-framework.org/
+
+REST_FRAMEWORK = {
+ 'DEFAULT_PERMISSION_CLASSES': [
+ 'rest_framework.permissions.IsAuthenticated',
+ ],
+}
+
+
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
diff --git a/breccia_mapper/templates/base.html b/breccia_mapper/templates/base.html
index e840c53..123d2ea 100644
--- a/breccia_mapper/templates/base.html
+++ b/breccia_mapper/templates/base.html
@@ -73,6 +73,10 @@
Activities
+
+ Network
+
+
{% if request.user.is_superuser %}
Admin
diff --git a/people/forms.py b/people/forms.py
index 9d7d3b6..e883607 100644
--- a/people/forms.py
+++ b/people/forms.py
@@ -23,9 +23,28 @@ class PersonForm(forms.ModelForm):
'country_of_residence': Select2Widget(),
'themes': Select2MultipleWidget(),
}
+
+
+class DynamicAnswerSetBase(forms.Form):
+ field_class = forms.ChoiceField
+ field_widget = None
+ field_required = True
+
+ 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 = self.field_class(label=question,
+ choices=choices,
+ widget=self.field_widget,
+ required=self.field_required)
+ self.fields['question_{}'.format(question.pk)] = field
-class RelationshipAnswerSetForm(forms.ModelForm):
+class RelationshipAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase):
"""
Form to allow users to describe a relationship.
@@ -37,17 +56,6 @@ class RelationshipAnswerSetForm(forms.ModelForm):
'relationship',
]
- 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.RelationshipAnswerSet:
# Save Relationship model
self.instance = super().save(commit=commit)
@@ -62,3 +70,12 @@ class RelationshipAnswerSetForm(forms.ModelForm):
self.instance.question_answers.add(answer)
return self.instance
+
+
+class NetworkFilterForm(DynamicAnswerSetBase):
+ """
+ Form to provide filtering on the network view.
+ """
+ field_class = forms.MultipleChoiceField
+ field_widget = Select2MultipleWidget
+ field_required = False
diff --git a/people/migrations/0017_answerset_replaced_timestamp.py b/people/migrations/0017_answerset_replaced_timestamp.py
new file mode 100644
index 0000000..01bf966
--- /dev/null
+++ b/people/migrations/0017_answerset_replaced_timestamp.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.10 on 2020-03-09 15:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('people', '0016_add_answer_set'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='relationshipanswerset',
+ name='replaced_timestamp',
+ field=models.DateTimeField(blank=True, editable=False, null=True),
+ ),
+ ]
diff --git a/people/models/relationship.py b/people/models/relationship.py
index 68e2eaf..9065ac8 100644
--- a/people/models/relationship.py
+++ b/people/models/relationship.py
@@ -152,4 +152,11 @@ class RelationshipAnswerSet(models.Model):
question_answers = models.ManyToManyField(RelationshipQuestionChoice)
#: When were these answers collected?
- timestamp = models.DateTimeField(auto_now_add=True)
+ timestamp = models.DateTimeField(auto_now_add=True,
+ editable=False)
+
+ replaced_timestamp = models.DateTimeField(blank=True, null=True,
+ editable=False)
+
+ def get_absolute_url(self):
+ return self.relationship.get_absolute_url()
diff --git a/people/templates/people/network.html b/people/templates/people/network.html
index 4c703eb..e0e3deb 100644
--- a/people/templates/people/network.html
+++ b/people/templates/people/network.html
@@ -9,6 +9,27 @@
+
+
@@ -16,37 +37,54 @@
{% endblock %}
{% block extra_script %}
+
+ {{ person_set|json_script:'person-set-data' }}
+
+ {{ relationship_set|json_script:'relationship-set-data' }}
+