From a93d0d594089108b0a682f182f352720c4b6f37d Mon Sep 17 00:00:00 2001
From: "N. Geisler" <ngeisler@fachschaft.informatik.tu-darmstadt.de>
Date: Mon, 11 May 2020 23:53:02 +0200
Subject: [PATCH] introduce REST API

add djangorestframework
add serializers for select models
create api urls
extend EventSlugMixin to work for list and create methods
create list and retrieve viewsets for select models
include AKModel URLS into main app
---
 AKModel/serializers.py | 39 +++++++++++++++++++++++++++
 AKModel/urls.py        | 23 ++++++++++++++++
 AKModel/views.py       | 61 +++++++++++++++++++++++++++++++++++++++++-
 AKPlanning/settings.py |  1 +
 AKPlanning/urls.py     |  1 +
 requirements.txt       |  1 +
 6 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 AKModel/serializers.py
 create mode 100644 AKModel/urls.py

diff --git a/AKModel/serializers.py b/AKModel/serializers.py
new file mode 100644
index 00000000..7993b622
--- /dev/null
+++ b/AKModel/serializers.py
@@ -0,0 +1,39 @@
+from rest_framework import serializers
+
+from AKModel.models import AK, Room, AKSlot, AKTrack, AKCategory, AKOwner
+
+
+class AKOwnerSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = AKOwner
+        fields = '__all__'
+
+
+class AKCategorySerializer(serializers.ModelSerializer):
+    class Meta:
+        model = AKCategory
+        fields = '__all__'
+
+
+class AKTrackSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = AKTrack
+        fields = '__all__'
+
+
+class AKSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = AK
+        fields = '__all__'
+
+
+class RoomSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Room
+        fields = '__all__'
+
+
+class AKSlotSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = AKSlot
+        fields = '__all__'
diff --git a/AKModel/urls.py b/AKModel/urls.py
new file mode 100644
index 00000000..71eb666e
--- /dev/null
+++ b/AKModel/urls.py
@@ -0,0 +1,23 @@
+from django.urls import include, path
+from rest_framework.routers import DefaultRouter
+
+from AKModel import views
+
+api_router = DefaultRouter()
+api_router.register('akowner', views.AKViewSet, basename='AKOwner')
+api_router.register('akcategory', views.AKViewSet, basename='AKCategory')
+api_router.register('aktrack', views.AKViewSet, basename='AKTrack')
+api_router.register('ak', views.AKViewSet, basename='AK')
+api_router.register('room', views.AKViewSet, basename='Room')
+api_router.register('akslot', views.AKViewSet, basename='AKSlot')
+
+app_name = 'model'
+
+urlpatterns = [
+    path(
+        '<slug:event_slug>/',
+        include([
+            path('api/', include(api_router.urls), name='api'),
+        ])
+    ),
+]
diff --git a/AKModel/views.py b/AKModel/views.py
index 1ef24635..88656ef7 100644
--- a/AKModel/views.py
+++ b/AKModel/views.py
@@ -1,6 +1,9 @@
 from django.shortcuts import get_object_or_404
+from rest_framework import viewsets, permissions, mixins
 
-from AKModel.models import Event
+from AKModel.models import Event, AK, AKSlot, Room, AKTrack, AKCategory, AKOwner
+from AKModel.serializers import AKSerializer, AKSlotSerializer, RoomSerializer, AKTrackSerializer, AKCategorySerializer, \
+    AKOwnerSerializer
 
 
 class EventSlugMixin:
@@ -21,6 +24,14 @@ class EventSlugMixin:
         self._load_event()
         return super().post(request, *args, **kwargs)
 
+    def list(self, request, *args, **kwargs):
+        self._load_event()
+        return super().list(request, *args, **kwargs)
+
+    def create(self, request, *args, **kwargs):
+        self._load_event()
+        return super().create(request, *args, **kwargs)
+
     def get_context_data(self, *, object_list=None, **kwargs):
         context = super().get_context_data(object_list=object_list, **kwargs)
         # Add event to context (to make it accessible in templates)
@@ -36,3 +47,51 @@ class FilterByEventSlugMixin(EventSlugMixin):
     def get_queryset(self):
         # Filter current queryset based on url event slug or return 404 if event slug is invalid
         return super().get_queryset().filter(event=self.event)
+
+
+class AKOwnerViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
+    permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
+    serializer_class = AKOwnerSerializer
+
+    def get_queryset(self):
+        return AKOwner.objects.filter(event=self.event)
+
+
+class AKCategoryViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
+    permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
+    serializer_class = AKCategorySerializer
+
+    def get_queryset(self):
+        return AKCategory.objects.filter(event=self.event)
+
+
+class AKTrackViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
+    permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
+    serializer_class = AKTrackSerializer
+
+    def get_queryset(self):
+        return AKTrack.objects.filter(event=self.event)
+
+
+class AKViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
+    permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
+    serializer_class = AKSerializer
+
+    def get_queryset(self):
+        return AK.objects.filter(event=self.event)
+
+
+class RoomViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
+    permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
+    serializer_class = RoomSerializer
+
+    def get_queryset(self):
+        return Room.objects.filter(event=self.event)
+
+
+class AKSlotViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
+    permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
+    serializer_class = AKSlotSerializer
+
+    def get_queryset(self):
+        return AKSlot.objects.filter(event=self.event)
diff --git a/AKPlanning/settings.py b/AKPlanning/settings.py
index 90d06a00..d3d55d88 100644
--- a/AKPlanning/settings.py
+++ b/AKPlanning/settings.py
@@ -46,6 +46,7 @@ INSTALLED_APPS = [
     'bootstrap4',
     'fontawesome_5',
     'timezone_field',
+    'rest_framework',
 ]
 
 MIDDLEWARE = [
diff --git a/AKPlanning/urls.py b/AKPlanning/urls.py
index c7c04a38..aa5f4538 100644
--- a/AKPlanning/urls.py
+++ b/AKPlanning/urls.py
@@ -19,6 +19,7 @@ from django.urls import path, include
 
 urlpatterns = [
     path('admin/', admin.site.urls),
+    path('', include('AKModel.urls', namespace='model')),
     path('i18n/', include('django.conf.urls.i18n'))
 ]
 
diff --git a/requirements.txt b/requirements.txt
index 7620f598..b06f5877 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,4 @@ django-bootstrap4==1.1.1
 django-fontawesome-5==1.0.16
 django-split-settings==1.0.1
 django-timezone-field==4.0
+djangorestframework==3.11.0
-- 
GitLab