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

borzechof99
committed
from django.http import JsonResponse, HttpResponse
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 the List of Sports on the Sport Homepage
TODO: More Documentation
"""
authentication_classes = []
# GET for api/admin/sport/
def list(self, request):
paginator = PageNumberWithPageSizePagination()
"""
Comments on Pagination:
Every list that needs to be paginated needs a paginator.
Here, the Paginator object is created in the GET call.
The Queryset which is supposed to be paginated needs to be run through the function:
> new_queryset = paginator.paginate_queryset(complete_queryset, request)
The new_queryset is a List, not a Manager, so it can be directly iterated upon.
After the data has been worked on and run through the Serializer as normal,
instead of returning Result(data), the paginator needs to be used again so it can add its page metadata:
> return paginator.get_paginated_response(serializer.data)
This function already returns a fully valid Response, so it can be directly returned.
"""
sports = Sport.objects.all()
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):
data_dict = SingleSportSerializer().to_internal_value(request)

borzechof99
committed
# A Try at Error Catching
if data_dict == None:

borzechof99
committed
return HttpResponse(status=400)

borzechof99
committed
new_sport = Sport.objects.create_sport()
new_sport.name = data_dict["name"]
new_sport.url = data_dict["url"]
# Before writing other Database Entries for Rating, the Sport needs to be saved once
new_sport.save()

borzechof99
committed
for criterion, value in data_dict["criteria"]:
new_sport.rate(criterion, value)
new_sport.save()
response = SingleSportSerializer(new_sport)
return Response(response.data)
# GET for api/admin/sport/<id>/
def retrieve(self, request, pk=None):
response = SingleSportSerializer(sport)
return Response(response.data)
# PUT for api/admin/sport/<id>/
def update(self, request, pk=None):
"""
TODO
"""
# Get Data from Serializer
request_data = SingleSportSerializer().to_internal_value(request)
if request_data == None:
# 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)
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# 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):
# Get Data from Serializer
request_data = SingleSportSerializer().to_internal_value(request)
if request_data == None:
# 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):
sport = get_object_or_404(Sport, pk=pk)
sport.delete()
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
return HttpResponse(status=404)
class IncompleteSportView(APIView):
authentication_classes = []
# GET for api/admin/sport/incomplete
def get(self, request):
incomplete_sport_list = []
for sport in Sport.objects.iterator():
if not sport.is_filled():
incomplete_sport_list.append(sport)
response = IncompleteSportSerializer(incomplete_sport_list)
return Response(response.data)
class CriteriaView(APIView):
"""
View for the List of Criteria and their Metadata
TODO: More Documentation
"""
authentication_classes = []
# GET for api/admin/criteria
def get(self, request):
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)