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 .serializers import (
SmallSportListSerializer,
SportListSerializer,
CriterionListSerializer,
QuestionListSerializer,
SingleSportSerializer,
)
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):
sports = Sport.objects.all()
criteria = Criterion.objects.all()
is_filled_tuples = []
for sport in sports.iterator():
filled_criteria_pks = []
# Get pks of Criteria which are connected to the sport
for criterion in sport.criteria_ratings.iterator():
filled_criteria_pks.append(criterion.pk)
is_filled = True
# Check every existing criterion whether it is in the generated list
for criterion in criteria.all():
if criterion.pk not in filled_criteria_pks:
# A criterion isn't filled out, so stop and set to false
is_filled = False
break
is_filled_tuples.append((sport, is_filled))
serializer = SmallSportListSerializer(is_filled_tuples)
return Response(serializer.data)
# POST for api/admin/sport/
def create(self, request):
data_dict = SingleSportSerializer().to_internal_value(request)
print(data_dict)
new_sport = 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()
for criterion in data_dict["criteria"]:
new_sport.rate(
Criterion.objects.get(pk=criterion["pk"]), criterion["value"]
)
new_sport.save()
response = SingleSportSerializer(new_sport)
return Response(response.data)
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# GET for api/admin/sport/<id>/
def retrieve(self, request, pk=None):
try:
sport = Sport.objects.get(pk=pk)
except:
return JsonResponse(
{
"status_code": 404,
"error": f"No Sport with ID {pk} found",
},
status=404,
)
return Response(SingleSportSerializer(sport).data)
# PUT for api/admin/sport/<id>/
def update(self, request, pk=None):
"""
TODO
"""
data_dict = SingleSportSerializer().to_internal_value(request)
sport = Sport.objects.get(pk=pk)
print(data_dict)
return Response({"test": "Updating a Single Entry"})
# DELETE for api/admin/sport/<id>/
def destroy(self, request, pk=None):
return Response({"test": "Removing a Single Entry"})
# Dev Notes:
# - This is a singular APIView which isn't meant to expose complete lists
# - It cannot be written into the Router, as it isn't a Viewset, so it is written directly into the urls.py's urlspatterns like this:
# path(r"api/admin/single-small-sport-list", views.SmallSportListAPIView.as_view())
# - The API isn't in the list in /api/admin because of that, but needs to be called manually here:
# http://localhost:8000/api/admin/single-small-sport-list