Compare commits

...

6 Commits

Author SHA1 Message Date
Sebastian Lohff 7158cef122 WIP user profile api 2020-02-02 02:10:33 +01:00
Sebastian Lohff 4361c4f44a Add REST API to webinterface 2020-02-02 01:48:10 +01:00
Sebastian Lohff ac29ea67c7 Allow regTime in user to be blank as well
Without regTime being blank a user with regTime NULL cannot be edited
via the admin interface
2020-02-01 16:53:27 +01:00
Sebastian Lohff 3fa752a354 Clarify choice of username at registration, again
Apparently it was still unclear to people what call they should use on
registration. Added extra message to explain this further.
2020-01-28 11:23:22 +01:00
Sebastian Lohff 75dd3ee413 clear_contest: make python3 ready, remove unused import 2020-01-26 11:36:57 +01:00
Sebastian Lohff 2eb43f7118 Bump django version to 1.11 2020-01-26 11:36:54 +01:00
15 changed files with 170 additions and 8 deletions

0
api/__init__.py Normal file
View File

3
api/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
api/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class ApiConfig(AppConfig):
name = 'api'

View File

3
api/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

63
api/serializers.py Normal file
View File

@ -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')

3
api/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

20
api/urls.py Normal file
View File

@ -0,0 +1,20 @@
from django.conf.urls import include, url
from rest_framework import routers
from .views import ContestViewSet, BandViewSet, FrequencyViewSet, EntryCategoryViewSet, ReferenceViewSet, QSOViewSet, \
ShadowCallViewSet, UserProfileView
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)
router.register('profile', UserProfileView, basename='profile')
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]

57
api/views.py Normal file
View File

@ -0,0 +1,57 @@
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.response import Response
from .serializers import ContestSerializer, BandSerializer, FrequencySerializer, EntryCategorySerializer, \
ReferenceSerializer, QSOSerializer, ShadowCallSerializer, UserSerializer
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 UserProfileView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
user = request.user
serializer = UserSerializer(user)
return Response(serializer.data)
class ShadowCallViewSet(viewsets.ReadOnlyModelViewSet):
permission_classes = [IsAdminUser]
queryset = ShadowCall.objects.all()
serializer_class = ShadowCallSerializer

View File

@ -1,8 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
from __future__ import print_function from __future__ import print_function
import datetime
# prepare environment # prepare environment
import sys import sys
sys.path.append("..") sys.path.append("..")
@ -11,7 +9,11 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cqtu.settings")
import django import django
django.setup() django.setup()
confirm = raw_input("Do are you sure you want to clear all contest data? Answer with uppercase YES: ") confirm_msg = "Do are you sure you want to clear all contest data? Answer with uppercase YES: "
try:
confirm = raw_input(confirm_msg)
except NameError:
confirm = input(confirm_msg)
if confirm != "YES": if confirm != "YES":
print("Aborting") print("Aborting")

View File

@ -53,7 +53,7 @@ class User(AbstractUser):
location = models.CharField(max_length=128, default="", blank=True) location = models.CharField(max_length=128, default="", blank=True)
opName = models.CharField(max_length=128, default="", blank=True) opName = models.CharField(max_length=128, default="", blank=True)
regTime = models.DateTimeField(null=True, default=None) regTime = models.DateTimeField(null=True, default=None, blank=True)
# because of cbr parsing bug, we sometimes have users who only have 70cm qsos # because of cbr parsing bug, we sometimes have users who only have 70cm qsos
# we ignore the band for them when checking QSOs # we ignore the band for them when checking QSOs

View File

@ -41,9 +41,11 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'crispy_forms', 'crispy_forms',
'rest_framework',
# local # local
'contest', 'contest',
'api',
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -34,6 +34,7 @@ urlpatterns = [
url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'), url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
url(r'^register/$', register, name='register'), url(r'^register/$', register, name='register'),
url(r'^profile/$', profile, name='profile'), url(r'^profile/$', profile, name='profile'),
url(r'^api/', include('api.urls')),
#url(r'^register/$', CreateView.as_view( #url(r'^register/$', CreateView.as_view(
# template_name='registration/register.html', # template_name='registration/register.html',
# form_class=CustomUserCreationForm, # form_class=CustomUserCreationForm,

View File

@ -1,2 +1,2 @@
Django==1.10 Django==1.11
django-crispy-forms django-crispy-forms

View File

@ -10,7 +10,10 @@
<div class="panel-body"> <div class="panel-body">
<p> <p>
Please register with your (uppercase) Callsign as Usernames. Please register with your (uppercase) Callsign as Usernames.
For DN-Calls, -[0-9] is allowed. For DN-Calls, -[0-9] is allowed (e.g. DN1ABC-2 for the second group).
</p>
<p>
Note: If you are a <strong>Ham/OM/YL</strong> please with your <strong>own</strong> callsign (e.g. DL7DOC). If you are a <strong>SWL</strong>, please use the <strong>DN-Call provided</strong> by your operator.
</p> </p>
<form method="POST" action="{% url 'register' %}"> <form method="POST" action="{% url 'register' %}">
{% csrf_token %} {% csrf_token %}