diff --git a/people/forms.py b/people/forms.py index 53ae15d..89ce80f 100644 --- a/people/forms.py +++ b/people/forms.py @@ -14,7 +14,9 @@ class OrganisationForm(forms.ModelForm): """Form for creating / updating an instance of :class:`Organisation`.""" class Meta: model = models.Organisation - fields = ['name', 'latitude', 'longitude'] + fields = [ + 'name' + ] class PersonForm(forms.ModelForm): @@ -74,7 +76,14 @@ class OrganisationAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase): """ class Meta: model = models.OrganisationAnswerSet - fields = [] + fields = [ + 'latitude', + 'longitude', + ] + widgets = { + 'latitude': forms.HiddenInput, + 'longitude': forms.HiddenInput, + } question_model = models.OrganisationQuestion answer_model = models.OrganisationQuestionChoice diff --git a/people/migrations/0036_move_latlng_to_answerset.py b/people/migrations/0036_move_latlng_to_answerset.py new file mode 100644 index 0000000..8a3dae3 --- /dev/null +++ b/people/migrations/0036_move_latlng_to_answerset.py @@ -0,0 +1,91 @@ +# Generated by Django 2.2.10 on 2021-02-24 15:29 + +from django.core.exceptions import ObjectDoesNotExist +from django.db import migrations, models + + +def migrate_forward(apps, schema_editor): + Organisation = apps.get_model('people', 'Organisation') + + fields = { + 'latitude', + 'longitude', + } + + for obj in Organisation.objects.all(): + try: + answer_set = obj.answer_sets.last() + if answer_set is None: + raise ObjectDoesNotExist + + except ObjectDoesNotExist: + answer_set = obj.answer_sets.create() + + for field in fields: + value = getattr(obj, field) + try: + setattr(answer_set, field, value) + + except TypeError: + # Cannot directly set an m2m field + m2m = getattr(answer_set, field) + m2m.set(value.all()) + + answer_set.save() + + +def migrate_backward(apps, schema_editor): + Organisation = apps.get_model('people', 'Organisation') + + fields = { + 'latitude', + 'longitude', + } + + for obj in Organisation.objects.all(): + try: + answer_set = obj.answer_sets.last() + + for field in fields: + value = getattr(answer_set, field) + try: + setattr(obj, field, value) + + except TypeError: + # Cannot directly set an m2m field + m2m = getattr(obj, field) + m2m.set(value.all()) + + obj.save() + + except ObjectDoesNotExist: + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('people', '0035_add_organisation_questions'), + ] + + operations = [ + migrations.AddField( + model_name='organisationanswerset', + name='latitude', + field=models.FloatField(blank=True, null=True), + ), + migrations.AddField( + model_name='organisationanswerset', + name='longitude', + field=models.FloatField(blank=True, null=True), + ), + migrations.RunPython(migrate_forward, migrate_backward), + migrations.RemoveField( + model_name='organisation', + name='latitude', + ), + migrations.RemoveField( + model_name='organisation', + name='longitude', + ), + ] diff --git a/people/models/person.py b/people/models/person.py index 015800f..e4459a4 100644 --- a/people/models/person.py +++ b/people/models/person.py @@ -93,12 +93,6 @@ class Organisation(models.Model): """Organisation to which a :class:`Person` belongs.""" name = models.CharField(max_length=255, blank=False, null=False) - #: Latitude for displaying location on a map - latitude = models.FloatField(blank=True, null=True) - - #: Longitude for displaying location on a map - longitude = models.FloatField(blank=True, null=True) - def __str__(self) -> str: return self.name @@ -119,6 +113,12 @@ class OrganisationAnswerSet(AnswerSet): blank=False, null=False) + #: Latitude for displaying location on a map + latitude = models.FloatField(blank=True, null=True) + + #: Longitude for displaying location on a map + longitude = models.FloatField(blank=True, null=True) + #: Answers to :class:`OrganisationQuestion`s question_answers = models.ManyToManyField(OrganisationQuestionChoice) @@ -130,7 +130,7 @@ class OrganisationAnswerSet(AnswerSet): """Get the answers from this set as a dictionary for use in Form.initial.""" exclude_fields = { 'id', - 'timestemp', + 'timestamp', 'replaced_timestamp', 'organisation_id', 'question_answers', @@ -298,7 +298,7 @@ class PersonAnswerSet(AnswerSet): """Get the answers from this set as a dictionary for use in Form.initial.""" exclude_fields = { 'id', - 'timestemp', + 'timestamp', 'replaced_timestamp', 'person_id', 'question_answers', diff --git a/people/templates/people/organisation/update.html b/people/templates/people/organisation/update.html index 1d75030..7b5aa44 100644 --- a/people/templates/people/organisation/update.html +++ b/people/templates/people/organisation/update.html @@ -33,7 +33,10 @@ {% csrf_token %} {% load bootstrap4 %} - {% bootstrap_form form %} + {% bootstrap_form form exclude='latitude,longitude' %} + + {% bootstrap_field form.latitude %} + {% bootstrap_field form.longitude %} {% buttons %} diff --git a/people/views/organisation.py b/people/views/organisation.py index 9c59cbf..6054ac9 100644 --- a/people/views/organisation.py +++ b/people/views/organisation.py @@ -31,11 +31,12 @@ class OrganisationDetailView(LoginRequiredMixin, DetailView): """Add map marker to context.""" context = super().get_context_data(**kwargs) - context['answer_set'] = self.object.current_answers + answerset = self.object.current_answers + context['answer_set'] = answerset context['map_markers'] = [{ 'name': self.object.name, - 'lat': self.object.latitude, - 'lng': self.object.longitude, + 'lat': getattr(answerset, 'latitude', None), + 'lng': getattr(answerset, 'longitude', None), }] return context @@ -53,10 +54,11 @@ class OrganisationUpdateView(LoginRequiredMixin, UpdateView): """Add map marker to context.""" context = super().get_context_data(**kwargs) + answerset = self.object.current_answers context['map_markers'] = [{ 'name': self.object.name, - 'lat': self.object.latitude, - 'lng': self.object.longitude, + 'lat': getattr(answerset, 'latitude', None), + 'lng': getattr(answerset, 'longitude', None), }] return context