diff --git a/activities/migrations/0004_activity_attendance_list.py b/activities/migrations/0004_activity_attendance_list.py new file mode 100644 index 0000000..33bd8f8 --- /dev/null +++ b/activities/migrations/0004_activity_attendance_list.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.10 on 2020-02-19 15:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('people', '0005_user_one_person'), + ('activities', '0003_rename_activity_series_fk'), + ] + + operations = [ + migrations.AddField( + model_name='activity', + name='attendance_list', + field=models.ManyToManyField(related_name='activities', to='people.Person'), + ), + ] diff --git a/activities/models.py b/activities/models.py index a5015eb..d9bb48a 100644 --- a/activities/models.py +++ b/activities/models.py @@ -1,6 +1,9 @@ from django.db import models +from people import models as people_models + + class ActivityType(models.Model): """ Representation of the type of activity being conducted. @@ -33,7 +36,7 @@ class ActivityMedium(models.Model): class ActivitySeries(models.Model): """ - A series of related :class:`Activity`s + A series of related :class:`Activity`s. """ class Meta: verbose_name_plural = 'activity series' @@ -58,7 +61,7 @@ class ActivitySeries(models.Model): class Activity(models.Model): """ - An instance of an activity - e.g. a workshop + An instance of an activity - e.g. a workshop. """ class Meta: verbose_name_plural = 'activities' @@ -73,15 +76,19 @@ class Activity(models.Model): on_delete=models.PROTECT, blank=True, null=True) - #: What type of activity does this series represent? + #: What type of activity is this? type = models.ForeignKey(ActivityType, on_delete=models.PROTECT, blank=False, null=False) - #: How are activities in this series typically conducted? + #: How was this activity conducted? medium = models.ForeignKey(ActivityMedium, on_delete=models.PROTECT, blank=False, null=False) + + #: Who attended this activity? + attendance_list = models.ManyToManyField(people_models.Person, + related_name='activities') def __str__(self) -> str: return self.name diff --git a/activities/templates/activities/activity/detail.html b/activities/templates/activities/activity/detail.html index 65ce469..5e1901d 100644 --- a/activities/templates/activities/activity/detail.html +++ b/activities/templates/activities/activity/detail.html @@ -10,6 +10,20 @@ + {% if user_is_attending %} + + + {% else %} + + + {% endif %} +
@@ -23,4 +37,91 @@
{{ activity.medium }}
+
+ + + + + + + + + + {% for person in activity.attendance_list.all %} + + + + + + {% empty %} + + + + {% endfor %} + +
Name
{{ person }} + Profile +
No records
+ + +{% endblock %} + + +{% block extra_script %} + {% endblock %} diff --git a/activities/urls.py b/activities/urls.py index 21039d7..c86fbdf 100644 --- a/activities/urls.py +++ b/activities/urls.py @@ -21,4 +21,8 @@ urlpatterns = [ path('activities/', views.ActivityDetailView.as_view(), name='activity.detail'), + + path('activities//attendance', + views.ActivityAttendanceView.as_view(), + name='activity.attendance'), ] diff --git a/activities/views.py b/activities/views.py index ae1b1c4..b8e63e4 100644 --- a/activities/views.py +++ b/activities/views.py @@ -1,9 +1,14 @@ """ Views for displaying / manipulating models within the Activities app. """ -from django.views.generic import DetailView, ListView +import json + +from django.http import HttpResponse +from django.views.generic import DetailView, ListView, View +from django.views.generic.detail import SingleObjectMixin from . import models +from people import models as people_models class ActivitySeriesListView(ListView): @@ -38,3 +43,44 @@ class ActivityDetailView(DetailView): """ model = models.Activity template_name = 'activities/activity/detail.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context['user_is_attending'] = self.object.attendance_list.filter(pk=self.request.user.person.pk).exists() + + return context + + +class ActivityAttendanceView(SingleObjectMixin, View): + """ + View to add or delete attendance of an activity. + """ + model = models.Activity + + def post(self, request, *args, **kwargs): + self.object = self.get_object() + + if request.is_ajax(): + data = json.loads(request.body) + + person = people_models.Person.objects.get(pk=data['pk']) + self.object.attendance_list.add(person) + + return HttpResponse(status=204) + + pass + + def delete(self, request, *args, **kwargs): + self.object = self.get_object() + + if request.is_ajax(): + data = json.loads(request.body) + + person = people_models.Person.objects.get(pk=data['pk']) + self.object.attendance_list.remove(person) + + return HttpResponse(status=204) + + pass + diff --git a/breccia_mapper/settings.py b/breccia_mapper/settings.py index ac01a23..e2b0c0f 100644 --- a/breccia_mapper/settings.py +++ b/breccia_mapper/settings.py @@ -234,3 +234,11 @@ CONSTANCE_CONFIG_FIELDSETS = { } CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend' + + +# Bootstrap settings +# See https://django-bootstrap4.readthedocs.io/en/latest/settings.html + +BOOTSTRAP4 = { + 'include_jquery': 'full', +} diff --git a/breccia_mapper/templates/base.html b/breccia_mapper/templates/base.html index a456b5b..a8ce452 100644 --- a/breccia_mapper/templates/base.html +++ b/breccia_mapper/templates/base.html @@ -7,7 +7,6 @@ -