Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 54 additions & 30 deletions src/apps/api/views/competitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
from leaderboards.models import Leaderboard
from utils.data import make_url_sassy
from api.permissions import IsOrganizerOrCollaborator
import logging
logger = logging.getLogger()
from datetime import datetime
from django.db import transaction


class CompetitionViewSet(ModelViewSet):
Expand Down Expand Up @@ -184,34 +184,58 @@ def create(self, request, *args, **kwargs):
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

def update(self, request, *args, **kwargs):
"""Mostly a copy of the underlying base update, however we return some additional data
in the response to remove a GET from the frontend"""
partial = kwargs.pop('partial', False)
instance = self.get_object()
data = request.data
# TODO - This is Temporary. Need to change Leaderboard to Phase connect to M2M and handle this correctly.
# save leaderboard individually, then pass pk to each phase
if 'leaderboards' in data:
leaderboard_data = data['leaderboards'][0]
if(leaderboard_data['id']):
leaderboard_instance = Leaderboard.objects.get(id=leaderboard_data['id'])
leaderboard = LeaderboardSerializer(leaderboard_instance, data=data['leaderboards'][0])
else:
leaderboard = LeaderboardSerializer(data=data['leaderboards'][0])
leaderboard.is_valid()
leaderboard.save()
leaderboard_id = leaderboard["id"].value
for phase in data['phases']:
phase['leaderboard'] = leaderboard_id

serializer = self.get_serializer(instance, data=data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)

if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
# Execute everything inside atomic transaction
with transaction.atomic():
"""Mostly a copy of the underlying base update, however we return some additional data
in the response to remove a GET from the frontend"""
partial = kwargs.pop('partial', False)
instance = self.get_object()
data = request.data
# TODO - This is Temporary. Need to change Leaderboard to Phase connect to M2M and handle this correctly.
# save leaderboard individually, then pass pk to each phase
if 'leaderboards' in data:
leaderboard_data = data['leaderboards'][0]
if(leaderboard_data['id']):
leaderboard_instance = Leaderboard.objects.get(id=leaderboard_data['id'])
leaderboard = LeaderboardSerializer(leaderboard_instance, data=data['leaderboards'][0])
else:
leaderboard = LeaderboardSerializer(data=data['leaderboards'][0])
leaderboard.is_valid()
leaderboard.save()
leaderboard_id = leaderboard["id"].value

for phase in data['phases']:
# Newly added phase from front-end has no id
# Add a phase first to get id
# add this phase id in each task
if 'id' not in phase:
# Create Phase object
new_phase_obj = Phase.objects.create(
status=phase["status"],
index=phase["index"],
start=datetime.strptime(phase['start'], "%B %d, %Y"),
end=datetime.strptime(phase['end'], "%B %d, %Y") if phase['end'] else None,
name=phase["name"],
description=phase["description"],
hide_output=phase["hide_output"],
competition=Competition.objects.get(id=data['id'])
)
# Get phase id
new_phase_id = new_phase_obj.id
# loop over phase tasks to add phase id in each task
for task in phase["tasks"]:
task['phase'] = new_phase_id

phase['leaderboard'] = leaderboard_id

serializer = self.get_serializer(instance, data=data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)

if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}

# Re-do serializer in detail version (i.e. for Collaborator data)
context = self.get_serializer_context()
Expand Down