# Serializers. Defines which fields from an object get to the JSON object # Also optionally define POST, PATCH methods (create, update) from rest_framework import serializers from rowers.models import ( Workout, Rower, FavoriteChart, VirtualRaceResult, VirtualRace, GeoCourse, StandardCollection, CourseStandard, GeoPolygon, GeoPoint, PlannedSession, ForceCurveAnalysis ) from django.core.exceptions import PermissionDenied import datetime # Serializers define the API representation. class RowerSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Rower fields = ( 'id', 'weightcategory', 'max', 'rest', 'ut2', 'ut1', 'at', 'tr', 'an', 'hrzones', 'powerzones', 'pw_ut2', 'pw_ut1', 'pw_at', 'pw_tr', 'pw_an', 'ftp', 'hrftp', 'sex', 'defaulttimezone', 'getimportantemails', 'adaptiveclass', ) class FavoriteChartSerializer(serializers.ModelSerializer): class Meta: model = FavoriteChart fields = ( 'id', 'xparam', 'yparam1', 'yparam2', 'plottype', 'workouttype', 'reststrokes', 'user' ) class CourseStandardSerializer(serializers.ModelSerializer): class Meta: model = CourseStandard fields = ( 'id', 'name', 'coursedistance', 'coursetime', 'agemin', 'agemax', 'boatclass', 'boattype', 'sex', 'weightclass', 'adaptiveclass', 'skillclass', 'standardcollection', ) class StandardCollectionSerializer(serializers.ModelSerializer): standards = CourseStandardSerializer(many=True, read_only=True) class Meta: model = StandardCollection fields = ( 'id', 'name', 'notes', 'active', 'standards' ) class ShortEntrySerializer(serializers.ModelSerializer): entrycategory = CourseStandardSerializer(read_only=True) class Meta: model = VirtualRaceResult fields = ( 'id', 'username', 'teamname', 'boattype', 'sex', 'age', 'adaptiveclass', 'skillclass', 'coursecompleted', 'distance', 'duration', 'points', 'entrycategory', ) class VirtualRaceSerializer(serializers.ModelSerializer): coursestandards = StandardCollectionSerializer(read_only=True) entries = ShortEntrySerializer(many=True, read_only=True) class Meta: model = VirtualRace fields = ( 'id', 'name', 'course', 'registration_closure', 'evaluation_closure', 'start_time', 'end_time', 'country', 'timezone', 'contact_phone', 'contact_email', 'entries', 'coursestandards', ) class PlannedSessionSerializer(serializers.ModelSerializer): class Meta: model = VirtualRace fields = ( 'id', 'name', 'comment', 'startdate', 'enddate', 'preferreddate', 'sessiontype', 'sessionvalue', 'sessionunit', 'sessionmode', 'course', 'approximate_distance', 'approximate_duration', # 'steps', 'fitfile' ) def create(self, validated_data): # pragma: no cover if self.context['request'].user.is_authenticated: r = Rower.objects.get(user=self.context['request'].user) else: raise PermissionDenied("Not allowed") ps = PlannedSession.objects.create(manager=r.user, **validated_data) ps.rower.add(r) ps.save() return ps class EntrySerializer(serializers.ModelSerializer): entrycategory = CourseStandardSerializer(read_only=True) race = VirtualRaceSerializer(read_only=True) class Meta: model = VirtualRaceResult fields = ( 'id', 'teamname', 'adaptiveclass', 'skillclass', 'race', 'distance', 'duration', 'points', 'boattype', 'sex', 'age', 'entrycategory', ) class WorkoutSerializer(serializers.ModelSerializer): class Meta: model = Workout fields = ( 'id', 'name', 'date', 'workouttype', 'starttime', 'startdatetime', 'distance', 'duration', 'averagehr', 'maxhr', 'notes', 'summary', 'boattype', 'timezone', 'forceunit', 'inboard', 'oarlength', 'privacy', 'rankingpiece', 'trimp', 'rscore', 'normp', 'duplicate', ) def create(self, validated_data): # pragma: no cover if self.context['request'].user.is_authenticated: r = Rower.objects.get(user=self.context['request'].user) else: raise PermissionDenied("Not allowed") d = validated_data['date'] t = validated_data['starttime'] rowdatetime = datetime.datetime(d.year, d.month, d.day, t.hour, t.minute, t.second) validated_data['startdatetime'] = rowdatetime validated_data['user'] = r return Workout.objects.create(**validated_data) def update(self, instance, validated_data): # pragma: no cover d = validated_data['date'] t = validated_data['starttime'] rowdatetime = datetime.datetime(d.year, d.month, d.day, t.hour, t.minute, t.second) instance.name = validated_data['name'] instance.date = validated_data['date'] instance.workouttype = validated_data['workouttype'] instance.duration = validated_data['duration'] instance.distance = validated_data['distance'] instance.starttime = validated_data['starttime'] instance.notes = validated_data['notes'] instance.summary = validated_data['summary'] instance.averagehr = validated_data['averagehr'] instance.maxhr = validated_data['maxhr'] instance.startdatetime = rowdatetime instance.timezone = validated_data['timezone'] instance.forceunit = validated_data['forceunit'] instance.inboard = validated_data['inboard'] instance.oarlength = validated_data['oarlength'] instance.privacy = validated_data['privacy'] instance.rankingpiece = validated_data['rankingpiece'] instance.save() return instance # This is just a fake one for URL registration purposes class StrokeDataSerializer(serializers.Serializer): workoutid = serializers.IntegerField strokedata = serializers.JSONField def create(self, workoutid, strokedata): # pragma: no cover """ Create and enter a new set of stroke data into the DB """ # do something return 1 class GeoPointSerializer(serializers.ModelSerializer): class Meta: model = GeoPoint fields = ( 'id', 'latitude', 'longitude', 'order_in_poly', ) extra_kwargs = {'id': {'read_only': False, 'required': True}} class ForceCurveAnalysisSerializer(serializers.ModelSerializer): class Meta: model = ForceCurveAnalysis fields = ( 'id', 'name', 'workout', 'dist_min', 'dist_max', 'spm_min', 'spm_max', 'work_min', 'work_max', 'include_rest_strokes' ) class GeoPolygonSerializer(serializers.ModelSerializer): points = GeoPointSerializer(many=True) class Meta: model = GeoPolygon fields = ( 'id', 'name', 'order_in_course', 'points', ) extra_kwargs = {'id': {'read_only': False, 'required': True}} class GeoCourseSerializer(serializers.ModelSerializer): polygons = GeoPolygonSerializer(many=True) class Meta: model = GeoCourse fields = ( 'id', 'name', 'distance', 'country', 'notes', 'polygons', ) def update(self, instance, validated_data): # pragma: no cover instance.name = validated_data.get('name', instance.name) instance.country = validated_data.get('country', instance.country) instance.notes = validated_data.get('notes', instance.notes) instance.save() polygons = validated_data.get('polygons') for polygon in polygons: polygon_id = polygon.get('id', None) if polygon_id: p = GeoPolygon.objects.get(id=polygon_id) p.name = polygon.get('name', p.name) p.order_in_course = polygon.get( 'order_in_course', p.order_in_course) p.save() points = polygon.get('points') for point in points: point_id = point.get('id', None) if point_id: pt = GeoPoint.objects.get(id=point_id) pt.latitude = point.get('latitude', pt.latitude) pt.longitude = point.get('longitude', pt.longitude) pt.order_in_poly = point.get( 'order_in_poly', pt.order_in_poly) pt.save() return instance