from rest_framework import serializers from .models import * from exercise.serializers import ExerciseSerializer from registered_user.serializers import GetRegisteredUserSerializer from muscle.models import ExerciseMuscle from equipment.models import WorkoutEquipment from video.models import Video from video.serializers import VideoSerializer from superset.serializers import SupersetSerializer, SupersetExerciseSerializer from superset.models import Superset, SupersetExercise from superset.helpers import * from .helpers import * class WorkoutExerciseSerializer(serializers.ModelSerializer): exercise = ExerciseSerializer(read_only=True) duration_audio = serializers.ReadOnlyField() weight_audio = serializers.ReadOnlyField() class Meta: model = WorkoutExercise fields = ('workout', 'exercise','weight','reps','duration','duration_audio','weight_audio', 'created_at',) class CompleteWorkoutSerializer(serializers.ModelSerializer): class Meta: model = CompletedWorkout exclude = ['registered_user'] def create(self, validated_data): registered_user_id = self.context.get("registered_user") registered_user = RegisteredUser.objects.get(id=registered_user_id) completed_workout = CompletedWorkout.objects.create( registered_user=registered_user, workout=validated_data['workout'], difficulty=validated_data['difficulty'], total_time=validated_data['total_time'], workout_start_time=validated_data['workout_start_time'], # Fix #5: KeyError 'notes' - use .get() with default notes=validated_data.get('notes', '') ) if "health_kit_workout_uuid" in validated_data: # Fix #6: wrong attribute name - model field is health_kit_workout_uuid completed_workout.health_kit_workout_uuid = validated_data['health_kit_workout_uuid'] completed_workout.save() return completed_workout class WorkoutSerializer(serializers.ModelSerializer): # exercise = WorkoutExerciseSerializer(source='workout_exercise_workout', many=True) registered_user = GetRegisteredUserSerializer(many=False, read_only=True) muscles = serializers.SerializerMethodField() equipment = serializers.SerializerMethodField() exercise_count = serializers.SerializerMethodField() class Meta: model = Workout fields = '__all__' # depth = 1 def get_muscles(self, obj): # Fix #16: Use prefetched data when available, fall back to query if hasattr(obj, '_prefetched_objects_cache') and 'superset_set' in obj._prefetched_objects_cache: exercise_ids = [] for superset in obj.superset_set.all(): for se in superset.supersetexercise_set.all(): exercise_ids.append(se.exercise_id) if not exercise_ids: return [] muscles_names = ExerciseMuscle.objects.filter(exercise__id__in=exercise_ids).values_list('muscle__name', flat=True) return list(set(muscles_names)) superset_ids = Superset.objects.filter(workout=obj).values_list('id') exercise_ids = SupersetExercise.objects.filter(superset__id__in=superset_ids).values_list('exercise__id') muscles_names = ExerciseMuscle.objects.filter(exercise__id__in=exercise_ids).values_list('muscle__name', flat=True) return list(set(muscles_names)) def get_equipment(self, obj): # Fix #16: Use prefetched data when available, fall back to query if hasattr(obj, '_prefetched_objects_cache') and 'superset_set' in obj._prefetched_objects_cache: exercise_ids = [] for superset in obj.superset_set.all(): for se in superset.supersetexercise_set.all(): exercise_ids.append(se.exercise_id) if not exercise_ids: return [] equipment_names = WorkoutEquipment.objects.filter(exercise__id__in=exercise_ids).values_list('equipment__name', flat=True) return list(set(equipment_names)) superset_ids = Superset.objects.filter(workout=obj).values_list('id') exercise_ids = SupersetExercise.objects.filter(superset__id__in=superset_ids).values_list('exercise__id') equipment_names = WorkoutEquipment.objects.filter(exercise__id__in=exercise_ids).values_list('equipment__name', flat=True) return list(set(equipment_names)) def get_exercise_count(self, obj): # Fix #16: Use prefetched data when available, fall back to query returnValue = 0 if hasattr(obj, '_prefetched_objects_cache') and 'superset_set' in obj._prefetched_objects_cache: for superset in obj.superset_set.all(): exercise_count = len(superset.supersetexercise_set.all()) returnValue += (superset.rounds * exercise_count) return returnValue supersets = Superset.objects.filter(workout=obj) for superset in supersets: exercise_count = SupersetExercise.objects.filter(superset=superset).count() returnValue += (superset.rounds * exercise_count) return returnValue class WorkoutDetailSerializer(serializers.ModelSerializer): supersets = serializers.SerializerMethodField() registered_user = serializers.SerializerMethodField() all_superset_exercise = serializers.SerializerMethodField() class Meta: model = Workout fields = ('id', 'name', 'description', 'supersets', 'registered_user', 'estimated_time', 'all_superset_exercise', ) depth = 1 def get_all_superset_exercise(self, obj): all_exercise_data = create_all_exercise_list_for_workout(obj) return all_exercise_data def get_supersets(self, obj): objs = Superset.objects.filter(workout=obj).order_by('order') data = SupersetSerializer(objs, many=True).data # add a beginning workout superset first_up_superset = get_first_up_superset(obj) first_up_superset_exercise = get_first_up_superset_exercise(first_up_superset) first_data = SupersetSerializer([first_up_superset], many=True).data __data = SupersetExerciseSerializer([first_up_superset_exercise], many=True).data first_data[0]["exercises"] = __data data[:0] = first_data return data def get_registered_user(self, obj): data = GetRegisteredUserSerializer(obj.registered_user, many=False).data return data class GetCompleteWorkoutSerializer(serializers.ModelSerializer): workout = WorkoutSerializer(many=False, read_only=True) class Meta: model = CompletedWorkout exclude = ['registered_user'] class POSTCompleteWorkoutSerializer(serializers.ModelSerializer): class Meta: model = Workout exclude = ['registered_user'] class PlannedWorkoutSerializer(serializers.ModelSerializer): workout = POSTCompleteWorkoutSerializer(many=False, read_only=True) class Meta: model = PlannedWorkout exclude = ['registered_user'] depth = 1 class POSTPlannedWorkoutSerializer(serializers.ModelSerializer): class Meta: model = PlannedWorkout exclude = ['registered_user'] def create(self, validated_data): registered_user_id = self.context.get("registered_user") registered_user = RegisteredUser.objects.get(id=registered_user_id) planned_workout = PlannedWorkout.objects.create( registered_user=registered_user, workout=validated_data['workout'], on_date=validated_data['on_date'] ) # Fix #18: removed redundant save() right after create() return planned_workout