from .models import Workout from superset.helpers import get_first_up_superset_exercise from superset.models import Superset, SupersetExercise from superset.serializers import SupersetExerciseSerializer import json def create_all_exercise_list_for_workout(workout): all_superset_exercise = [] # add a beginning workout superset first_up_superset_exercise = get_first_up_superset_exercise(None) data = SupersetExerciseSerializer(first_up_superset_exercise, many=False).data audio_queues = default_beeps() superset = Superset.objects.filter(workout=workout).order_by('order').first() if superset is not None: supersetExercise = SupersetExercise.objects.filter(superset=superset).order_by('order').first() if supersetExercise is not None: next_up_data = { "audio_url": supersetExercise.exercise.audio_url().lower(), "play_at": 7 } starting_off_with = { "audio_url": "/media/transitions_audio/starting_off_with.m4a", "play_at": 8 } audio_queues.append(next_up_data) audio_queues.append(starting_off_with) data["audio_queues"] = audio_queues all_superset_exercise.append(data) # Fix #17: N+1 - add prefetch_related to avoid per-superset queries supersets = Superset.objects.filter(workout=workout).order_by('order').prefetch_related( 'supersetexercise_set__exercise' ) order = 2 for superset_count, superset in enumerate(supersets): # Use prefetched data instead of re-querying (N+1 fix) supersetExercises = sorted(superset.supersetexercise_set.all(), key=lambda se: se.order) for x in range(superset.rounds): for exercise_idx, exercise in enumerate(supersetExercises): exercise.order = order ser_data = SupersetExerciseSerializer(exercise, many=False).data ser_data.mutable = True audio_queues = default_beeps() if exercise.duration is not None and exercise.duration > 0 : coming_up_data = { "audio_url": "/media/transitions_audio/coming_up.m4a", "play_at": 8 } audio_queues.append(coming_up_data) if len(supersetExercises) > exercise_idx+1: next_exercise = supersetExercises[exercise_idx+1] next_up_data = { "audio_url": next_exercise.exercise.audio_url().lower(), "play_at": 7 } audio_queues.append(next_up_data) elif x < superset.rounds - 1: first_exercise = supersetExercises.first() next_up_data = { "audio_url": first_exercise.exercise.audio_url().lower(), "play_at": 7 } audio_queues.append(next_up_data) elif len(supersets) > superset_count+1: next_superset = supersets[superset_count+1] # Use prefetched data instead of re-querying next_superset_exercises = sorted(next_superset.supersetexercise_set.all(), key=lambda se: se.order) next_supersetExercises = next_superset_exercises[0] if next_superset_exercises else None next_up_data = { "audio_url": next_supersetExercises.exercise.audio_url().lower(), "play_at": 7 } audio_queues.append(next_up_data) ser_data["audio_queues"] = audio_queues all_superset_exercise.append(ser_data) order += 1 return all_superset_exercise def default_beeps(): short_beep_start = 5 short_beep_end = 2 long_beep_start = 1 audio_queues = [] for x in range(short_beep_end, short_beep_start): audio_queues.append({ "play_at" : x, "audio_url": "short_beep", }) audio_queues.append({ "play_at" : long_beep_start, "audio_url": "long_beep", }) return audio_queues