From ddb09d148ea7e56760bfc506ead418c1a20a76dc Mon Sep 17 00:00:00 2001 From: Sebastian Lohff Date: Sun, 2 Feb 2020 01:48:10 +0100 Subject: [PATCH] Add REST API to webinterface --- api/__init__.py | 0 api/admin.py | 3 ++ api/apps.py | 5 +++ api/migrations/__init__.py | 0 api/models.py | 3 ++ api/serializers.py | 63 ++++++++++++++++++++++++++++++++++++++ api/tests.py | 3 ++ api/urls.py | 19 ++++++++++++ api/views.py | 52 +++++++++++++++++++++++++++++++ cqtu/settings.py | 2 ++ cqtu/urls.py | 1 + requirements.txt | 1 + 12 files changed, 152 insertions(+) create mode 100644 api/__init__.py create mode 100644 api/admin.py create mode 100644 api/apps.py create mode 100644 api/migrations/__init__.py create mode 100644 api/models.py create mode 100644 api/serializers.py create mode 100644 api/tests.py create mode 100644 api/urls.py create mode 100644 api/views.py diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..d87006d --- /dev/null +++ b/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + name = 'api' diff --git a/api/migrations/__init__.py b/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/models.py b/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/api/serializers.py b/api/serializers.py new file mode 100644 index 0000000..5b9bc4d --- /dev/null +++ b/api/serializers.py @@ -0,0 +1,63 @@ +from rest_framework import serializers + +from contest.models import Contest, Band, Frequency, QSO, EntryCategory, User, ShadowCall, Reference + + +class ContestSerializer(serializers.ModelSerializer): + class Meta: + model = Contest + # FIXME: add callQrg + fields = ('id', 'shortName', 'deadline', 'qsoStartTime', 'qsoEndTime', 'callQrg') + + +class BandSerializer(serializers.ModelSerializer): + # contest = ContestSerializer() + + class Meta: + model = Band + fields = ('id', 'name', 'contest') + + +class FrequencySerializer(serializers.ModelSerializer): + # band = BandSerializer() + + class Meta: + model = Frequency + fields = ('id', 'channel', 'qrg', 'band', 'note') + + +class EntryCategorySerializer(serializers.ModelSerializer): + class Meta: + model = EntryCategory + fields = ('id', 'name', 'description') + + +class ReferenceSerializer(serializers.ModelSerializer): + class Meta: + model = Reference + fields = ('id', 'name', 'description') + + +class UserSerializer(serializers.ModelSerializer): + ref = ReferenceSerializer() + cat = EntryCategorySerializer() + + class Meta: + model = User + fields = ('id', 'ref', 'cat', 'location', 'opName', 'regTime', 'dncall', 'qrv2m', 'qrv70cm', 'extra2m70cm') + + +class QSOSerializer(serializers.ModelSerializer): + # owner = UserSerializer() + + class Meta: + model = QSO + fields = ('id', 'owner', 'time', 'call', 'callRef', 'remarks') + + +class ShadowCallSerializer(serializers.ModelSerializer): + ref = ReferenceSerializer() + + class Meta: + model = ShadowCall + fields = ('id', 'username', 'ref', 'location', 'opName', 'regTime') diff --git a/api/tests.py b/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api/urls.py b/api/urls.py new file mode 100644 index 0000000..408cad4 --- /dev/null +++ b/api/urls.py @@ -0,0 +1,19 @@ +from django.conf.urls import include, url +from rest_framework import routers + +from .views import ContestViewSet, BandViewSet, FrequencyViewSet, EntryCategoryViewSet, ReferenceViewSet, QSOViewSet, \ + ShadowCallViewSet + +router = routers.DefaultRouter() +router.register('contests', ContestViewSet) +router.register('bands', BandViewSet) +router.register('frequencies', FrequencyViewSet) +router.register('entrycategories', EntryCategoryViewSet) +router.register('references', ReferenceViewSet) +router.register('qsos', QSOViewSet, basename='qso') +router.register('shadowcalls', ShadowCallViewSet) + +urlpatterns = [ + url(r'^', include(router.urls)), + url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), +] diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..86d5cae --- /dev/null +++ b/api/views.py @@ -0,0 +1,52 @@ +from rest_framework import viewsets +from rest_framework.permissions import IsAuthenticated, IsAdminUser + + +from .serializers import ContestSerializer, BandSerializer, FrequencySerializer, EntryCategorySerializer, \ + ReferenceSerializer, QSOSerializer, ShadowCallSerializer +from contest.models import Contest, Band, Frequency, EntryCategory, Reference, QSO, ShadowCall + + +class ContestViewSet(viewsets.ReadOnlyModelViewSet): + queryset = Contest.objects.all() + serializer_class = ContestSerializer + + +class BandViewSet(viewsets.ReadOnlyModelViewSet): + queryset = Band.objects.all() + serializer_class = BandSerializer + + +class FrequencyViewSet(viewsets.ReadOnlyModelViewSet): + queryset = Frequency.objects.all() + serializer_class = FrequencySerializer + + +class EntryCategoryViewSet(viewsets.ReadOnlyModelViewSet): + queryset = EntryCategory.objects.all() + serializer_class = EntryCategorySerializer + + +class ReferenceViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [IsAdminUser] + queryset = Reference.objects.all() + serializer_class = ReferenceSerializer + + +class QSOViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [IsAuthenticated] + serializer_class = QSOSerializer + + def get_queryset(self): + return QSO.objects.filter(owner=self.request.user) + + +class UserProfile(viewsets.ReadOnlyModelViewSet): + """Return the currently authenticated user as a single item""" + pass + + +class ShadowCallViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [IsAdminUser] + queryset = ShadowCall.objects.all() + serializer_class = ShadowCallSerializer diff --git a/cqtu/settings.py b/cqtu/settings.py index f5eb3c6..b1760a9 100644 --- a/cqtu/settings.py +++ b/cqtu/settings.py @@ -41,9 +41,11 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'crispy_forms', + 'rest_framework', # local 'contest', + 'api', ] MIDDLEWARE = [ diff --git a/cqtu/urls.py b/cqtu/urls.py index b869c81..66d856c 100644 --- a/cqtu/urls.py +++ b/cqtu/urls.py @@ -34,6 +34,7 @@ urlpatterns = [ url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'), url(r'^register/$', register, name='register'), url(r'^profile/$', profile, name='profile'), + url(r'^api/', include('api.urls')), #url(r'^register/$', CreateView.as_view( # template_name='registration/register.html', # form_class=CustomUserCreationForm, diff --git a/requirements.txt b/requirements.txt index 72f63ee..d864032 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ Django<1.12 django-crispy-forms +django-rest-framework