diff --git a/backend/secfit/workouts/serializers.py b/backend/secfit/workouts/serializers.py index 98036eec0661f5b05201221987788c30cf6b96eb..059af10c7d3892854015fbb6e9f68f3f197fcb50 100644 --- a/backend/secfit/workouts/serializers.py +++ b/backend/secfit/workouts/serializers.py @@ -109,33 +109,13 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer): return workout - def update(self, instance, validated_data): - """Custom logic for updating a Workout with its ExerciseInstances and Workouts. - - This is needed because each object in both exercise_instances and files must be iterated - over and handled individually. - - Args: - instance (Workout): Current Workout object - validated_data: Contains data for validated fields - - Returns: - Workout: Updated Workout instance - """ - exercise_instances_data = validated_data.pop("exercise_instances") - exercise_instances = instance.exercise_instances - - instance.name = validated_data.get("name", instance.name) - instance.notes = validated_data.get("notes", instance.notes) - instance.visibility = validated_data.get("visibility", instance.visibility) - instance.date = validated_data.get("date", instance.date) - instance.save() - - # Handle ExerciseInstances - + def handle_exercise_instance(self, instance, validated_data): # This updates existing exercise instances without adding or deleting object. # zip() will yield n 2-tuples, where n is # min(len(exercise_instance), len(exercise_instance_data)) + exercise_instances_data = validated_data.pop("exercise_instances") + exercise_instances = instance.exercise_instances + for exercise_instance, exercise_instance_data in zip( exercise_instances.all(), exercise_instances_data ): @@ -162,30 +142,54 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer): for i in range(len(exercise_instances_data), len(exercise_instances.all())): exercise_instances.all()[i].delete() - # Handle WorkoutFiles + def handle_workout_files(self, instance, validated_data): + files_data = validated_data.pop("files") + files = instance.files + + for file, file_data in zip(files.all(), files_data): + file.file = file_data.get("file", file.file) + + # If new files have been added, creating new WorkoutFiles + if len(files_data) > len(files.all()): + for i in range(len(files.all()), len(files_data)): + WorkoutFile.objects.create( + workout=instance, + owner=instance.owner, + file=files_data[i].get("file"), + ) + # Else if files have been removed, delete WorkoutFiles + elif len(files_data) < len(files.all()): + for i in range(len(files_data), len(files.all())): + files.all()[i].delete() + + def update(self, instance, validated_data): + """Custom logic for updating a Workout with its ExerciseInstances and Workouts. + + This is needed because each object in both exercise_instances and files must be iterated + over and handled individually. + + Args: + instance (Workout): Current Workout object + validated_data: Contains data for validated fields + + Returns: + Workout: Updated Workout instance + """ + + instance.name = validated_data.get("name", instance.name) + instance.notes = validated_data.get("notes", instance.notes) + instance.visibility = validated_data.get("visibility", instance.visibility) + instance.date = validated_data.get("date", instance.date) + instance.save() + + self.handle_exercise_instance(instance, validated_data) if "files" in validated_data: - files_data = validated_data.pop("files") - files = instance.files - - for file, file_data in zip(files.all(), files_data): - file.file = file_data.get("file", file.file) - - # If new files have been added, creating new WorkoutFiles - if len(files_data) > len(files.all()): - for i in range(len(files.all()), len(files_data)): - WorkoutFile.objects.create( - workout=instance, - owner=instance.owner, - file=files_data[i].get("file"), - ) - # Else if files have been removed, delete WorkoutFiles - elif len(files_data) < len(files.all()): - for i in range(len(files_data), len(files.all())): - files.all()[i].delete() + self.handle_workout_files(instance, validated_data) return instance + def get_owner_username(self, obj): """Returns the owning user's username