diff --git a/breccia_mapper/templates/base.html b/breccia_mapper/templates/base.html index 4aac740..faf19a4 100644 --- a/breccia_mapper/templates/base.html +++ b/breccia_mapper/templates/base.html @@ -66,6 +66,10 @@ People + + diff --git a/people/forms.py b/people/forms.py index b4addcb..d1495d9 100644 --- a/people/forms.py +++ b/people/forms.py @@ -24,6 +24,17 @@ def get_date_year_range() -> typing.Iterable[int]: return range(this_year, this_year - num_years_display, -1) +class OrganisationForm(forms.ModelForm): + """Form for creating / updating an instance of :class:`Organisation`.""" + class Meta: + model = models.Organisation + fields = [ + 'name', + 'latitude', + 'longitude' + ] + + class PersonForm(forms.ModelForm): """Form for creating / updating an instance of :class:`Person`.""" class Meta: diff --git a/people/models/person.py b/people/models/person.py index c397281..a472f82 100644 --- a/people/models/person.py +++ b/people/models/person.py @@ -64,9 +64,7 @@ class User(AbstractUser): class Organisation(models.Model): - """ - Organisation to which a :class:`Person` belongs. - """ + """Organisation to which a :class:`Person` belongs.""" name = models.CharField(max_length=255, blank=False, null=False) #: Latitude for displaying location on a map @@ -78,6 +76,9 @@ class Organisation(models.Model): def __str__(self) -> str: return self.name + def get_absolute_url(self): + return reverse('people:organisation.detail', kwargs={'pk': self.pk}) + class Theme(models.Model): """ diff --git a/people/templates/people/organisation/create.html b/people/templates/people/organisation/create.html new file mode 100644 index 0000000..5c714ae --- /dev/null +++ b/people/templates/people/organisation/create.html @@ -0,0 +1,29 @@ +{% extends 'base.html' %} + +{% block content %} + + +

New Organisation

+ +
+ +
+ {% csrf_token %} + + {% load bootstrap4 %} + {% bootstrap_form form %} + + {% buttons %} + + {% endbuttons %} +
+ +{% endblock %} diff --git a/people/templates/people/organisation/detail.html b/people/templates/people/organisation/detail.html new file mode 100644 index 0000000..5d01d2e --- /dev/null +++ b/people/templates/people/organisation/detail.html @@ -0,0 +1,36 @@ +{% extends 'base.html' %} + +{% block extra_head %} + {{ map_markers|json_script:'map-markers' }} + + {% load staticfiles %} + + + +{% endblock %} + +{% block content %} + + +

{{ organisation.name }}

+ +
+ + Update + +
+ +
+ +
+ +{% endblock %} diff --git a/people/templates/people/organisation/list.html b/people/templates/people/organisation/list.html new file mode 100644 index 0000000..39370e2 --- /dev/null +++ b/people/templates/people/organisation/list.html @@ -0,0 +1,42 @@ +{% extends 'base.html' %} + +{% block content %} + + +

People

+ +
+ + New Organisation + + + + + + + + + + {% for organisation in organisation_list.all %} + + + + + + {% empty %} + + + + {% endfor %} + +
Name
{{ organisation }} + Details +
No records
+ +{% endblock %} diff --git a/people/templates/people/organisation/update.html b/people/templates/people/organisation/update.html new file mode 100644 index 0000000..d79d315 --- /dev/null +++ b/people/templates/people/organisation/update.html @@ -0,0 +1,68 @@ +{% extends 'base.html' %} + +{% block extra_head %} + {% load staticfiles %} + + + + + + + +{% endblock %} + +{% block content %} + + +

{{ organisation.name }}

+ +
+ +
+ {% csrf_token %} + + {% load bootstrap4 %} + {% bootstrap_form form exclude='latitude,longitude' %} + + {% bootstrap_field form.latitude %} + {% bootstrap_field form.longitude %} + + {% buttons %} + + {% endbuttons %} +
+ +
+ + +
+ +
+ +{% endblock %} diff --git a/people/urls.py b/people/urls.py index 9fa4f32..955d343 100644 --- a/people/urls.py +++ b/people/urls.py @@ -6,6 +6,22 @@ from . import views app_name = 'people' urlpatterns = [ + path('organisations/create', + views.organisation.OrganisationCreateView.as_view(), + name='organisation.create'), + + path('organisations', + views.organisation.OrganisationListView.as_view(), + name='organisation.list'), + + path('organisations/', + views.organisation.OrganisationDetailView.as_view(), + name='organisation.detail'), + + path('organisations//update', + views.organisation.OrganisationUpdateView.as_view(), + name='organisation.update'), + path('profile/', views.person.ProfileView.as_view(), name='person.profile'), diff --git a/people/views/__init__.py b/people/views/__init__.py index e7ddb60..26a117e 100644 --- a/people/views/__init__.py +++ b/people/views/__init__.py @@ -4,6 +4,7 @@ Views for displaying or manipulating models within the `people` app. from . import ( network, + organisation, person, relationship ) @@ -11,6 +12,7 @@ from . import ( __all__ = [ 'network', + 'organisation', 'person', 'relationship', ] diff --git a/people/views/organisation.py b/people/views/organisation.py new file mode 100644 index 0000000..b405923 --- /dev/null +++ b/people/views/organisation.py @@ -0,0 +1,47 @@ +import typing + +from django.contrib.auth.mixins import LoginRequiredMixin +from django.views.generic import CreateView, DetailView, ListView, UpdateView + +from people import forms, models + + +class OrganisationCreateView(LoginRequiredMixin, CreateView): + """View to create a new instance of :class:`Organisation`.""" + model = models.Organisation + template_name = 'people/organisation/create.html' + form_class = forms.OrganisationForm + + +class OrganisationListView(LoginRequiredMixin, ListView): + """View displaying a list of :class:`organisation` objects.""" + model = models.Organisation + template_name = 'people/organisation/list.html' + + +class OrganisationDetailView(LoginRequiredMixin, DetailView): + """View displaying details of a :class:`Organisation`.""" + model = models.Organisation + context_object_name = 'organisation' + template_name = 'people/organisation/detail.html' + + def get_context_data(self, + **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + """Add map marker to context.""" + context = super().get_context_data(**kwargs) + + context['map_markers'] = [{ + 'name': self.object.name, + 'lat': self.object.latitude, + 'lng': self.object.longitude, + }] + + return context + + +class OrganisationUpdateView(LoginRequiredMixin, UpdateView): + """View for updating a :class:`Organisation` record.""" + model = models.Organisation + context_object_name = 'organisation' + template_name = 'people/organisation/update.html' + form_class = forms.OrganisationForm