Newer
Older
"""
Defines the views for the API
"""
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from .pagination import PageNumberWithPageSizePagination
from .serializers import (
SmallSportListSerializer,
SportListSerializer,
CriterionListSerializer,
QuestionListSerializer,
SingleSportSerializer,
CriteriaSerializer,
IncompleteSportSerializer,
)
from .models import Sport, Criterion, Question
class SportListView(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
"""
A View returning every Sport Object
"""
serializer_class = SportListSerializer
queryset = Sport.objects.all()
class CriterionListView(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
"""
A View returning every Criterion Object
"""
serializer_class = CriterionListSerializer
queryset = Criterion.objects.all()
class QuestionListView(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
"""
A View returning every Question Object
"""
serializer_class = QuestionListSerializer
queryset = Question.objects.all()
# Dev Notes:
# - If we want to include a View in the Router in urls.py, the View needs to be a Viewset
# - Those are mostly meant for Lists of Objects, so instead of get() and post(), list() and create() are used respectively
# https://stackoverflow.com/questions/30389248/how-can-i-register-a-single-view-not-a-viewset-on-my-router
class SmallSportListView(viewsets.ViewSet):
"""
View for Sports and List of Sport:
List returns every Sport with the is_filled Field
Detail returns single Sports with every Criterium
authentication_classes = []
# GET for api/admin/sport/
def list(self, request):
GET for api/admin/sport/
Returns a List of Every Sport with the is_filled Field, stating whether every Criterion is given a Rating or not
sports = Sport.objects.all().order_by("name")
sports = paginator.paginate_queryset(sports, request)
is_filled_tuples = []

borzechof99
committed
is_filled_tuples.append((sport, sport.is_filled()))
serializer = SmallSportListSerializer(is_filled_tuples)
return paginator.get_paginated_response(serializer.data)
# POST for api/admin/sport/
def create(self, request):
"""
POST for api/admin/sport/
View for Creating a New Sport
"""
request_data = SingleSportSerializer().to_internal_value(request)

borzechof99
committed
# A Try at Error Catching

borzechof99
committed
return HttpResponse(status=400)

borzechof99
committed
new_sport = Sport.objects.create_sport()
new_sport.name = request_data["name"]
new_sport.url = request_data["url"]
new_sport.save()
response = SingleSportSerializer(new_sport)
return Response(response.data)
# GET for api/admin/sport/<id>/
def retrieve(self, request, pk=None):
"""
GET for api/admin/sport/<pk>/
View for getting a Single Sport, with the pk to the Sport being the argument in the URL
"""
response = SingleSportSerializer(sport)
return Response(response.data)
# PUT for api/admin/sport/<id>/
def update(self, request, pk=None):
"""
PUT for api/admin/sport/<id>/
Creates a Sport if it doesn't exist, otherwise overwrites it.
TODO: Maybe Rework PUT if needed of Admin Frontend
# Get Data from Serializer
request_data = SingleSportSerializer().to_internal_value(request)
# Something is Broke, so Refuse Changing Data
return HttpResponse(status=400)
# Get Sport from Data
sport = Sport.objects.get(pk=pk)
# Apply New Data to Sport
sport.name = request_data["name"]
sport.url = request_data["url"]
# Overwrite Criterion Ratings
for criterion, value in request_data["criteria"]:
sport.rate(criterion, value)
# Re-Serialize changed Sport and Send it back
response = SingleSportSerializer(sport)
return Response(response.data)
# PATCH for api/admin/sport/<id>/
def partial_update(self, request, pk=None):
"""
PATCH for api/admin/sport/<id>/
Fills in the given Values into the Sport specified in the URL
"""
# Get Data from Serializer
request_data = SingleSportSerializer().to_internal_value(request)
# Something is Broke, so Refuse Changing Data
return HttpResponse(status=400)
# Get Sport from Data
sport = Sport.objects.get(pk=pk)
# Apply New Data to Sport, if it exists
if "name" in request_data.keys():
sport.name = request_data["name"]
if "url" in request_data.keys():
sport.url = request_data["url"]
# Overwrite Criterion Ratings
for criterion, value in request_data["criteria"]:
sport.rate(criterion, value)
# Re-Serialize changed Sport and Send it back
response = SingleSportSerializer(sport)
return Response(response.data)
# DELETE for api/admin/sport/<id>/
def destroy(self, request, pk=None):
"""
DELETE for api/admin/sport/<id>/
Removes Sport Object specified in the URL
"""
sport = get_object_or_404(Sport, pk=pk)
sport.delete()
return HttpResponse(status=404)
class IncompleteSportView(APIView):
"""
Returns all Sport Objects with Incomplete Ratings
"""
authentication_classes = []
def get(self, request):
Returns every incomplete Sport with its incomplete Ratings in a paginated manner
paginator = PageNumberWithPageSizePagination()
queryset = Sport.objects.iterator()
queryset = paginator.paginate_queryset(queryset, request)
incomplete_sport_list = []
if not sport.is_filled():
incomplete_sport_list.append(sport)
response = IncompleteSportSerializer(incomplete_sport_list)
return paginator.get_paginated_response(response.data)
class CriteriaView(APIView):
"""
View for the List of Criteria and their Metadata
"""
authentication_classes = []
def get(self, request):
"""
GET for api/admin/criteria/
Returns every Criterium and the Metadata of
Number of Sports in which the Rating is >1
and the cumulated sum of Ratings >1
data = []
for crit in Criterion.objects.iterator():
active_sports, sum_of_weights = crit.get_active_sum()
data.append((crit, active_sports, sum_of_weights))
response = CriteriaSerializer(data)
return Response(response.data)