Coverage for events/serializers.py: 63%
173 statements
« prev ^ index » next coverage.py v6.4.4, created at 2022-10-14 16:23 -0500
« prev ^ index » next coverage.py v6.4.4, created at 2022-10-14 16:23 -0500
1from rest_framework import serializers
2from users.models import User
3from .models import Event, Challenge, Team, Score, Participant, StationCheckIn, Station
6class TeamScoreSerializer(serializers.ModelSerializer):
7 class Meta:
8 model = Team
9 fields = ["random_slug", "name", "total_score"]
10 extra_kwargs = {
11 "total_score": {"read_only": True},
12 }
15class ChallengeSerializer(serializers.ModelSerializer):
16 score = serializers.SerializerMethodField(read_only=True)
18 class Meta:
19 model = Challenge
20 fields = ["random_slug", "event", "name", "status", "score", "type_of"]
21 extra_kwargs = {"status": {"read_only": True}}
23 def get_score(self, challenge):
24 try:
25 participant = Participant.objects.get(
26 event=challenge.event, user=self.context.get("user")
27 )
28 score = challenge.scores.get(team=participant.team)
29 return score.score
30 except (Participant.DoesNotExist, Score.DoesNotExist):
31 return None
34class EventSerializer(serializers.ModelSerializer):
35 owner = serializers.CharField(source="owner.name", read_only=True)
36 is_master_of_ceremony = serializers.SerializerMethodField(read_only=True)
38 class Meta:
39 model = Event
40 fields = [
41 "random_slug",
42 "name",
43 "date",
44 "image",
45 "owner",
46 "is_master_of_ceremony",
47 ]
49 def get_is_master_of_ceremony(self, event):
50 try:
51 participant = Participant.objects.get(
52 event=event, user=self.context.get("user")
53 )
54 return participant.is_master_of_ceremony
55 except Participant.DoesNotExist:
56 return None
59class ParticipantDetailSerializer(serializers.ModelSerializer):
60 event = EventSerializer(read_only=True)
61 invited_by = serializers.CharField(source="invited_by.email", read_only=True)
63 class Meta:
64 model = Participant
65 fields = ["random_slug", "event", "is_master_of_ceremony", "rsvp", "invited_by"]
68class ParticipantSerializer(serializers.ModelSerializer):
69 email = serializers.EmailField(source="user.email")
71 class Meta:
72 model = Participant
73 fields = ["random_slug", "email", "event", "is_master_of_ceremony"]
75 def create(self, validated_data):
76 email = validated_data.get("user").get("email")
77 user, _ = User.objects.get_or_create(email=email)
78 validated_data["user"] = user
79 participant, _ = Participant.objects.get_or_create(**validated_data)
80 return participant
83class TeamSerializer(serializers.ModelSerializer):
84 members = ParticipantSerializer(many=True, read_only=True)
86 class Meta:
87 model = Team
88 fields = ["random_slug", "name", "members", "event"]
89 extra_kwargs = {"event": {"write_only": True}}
92class EventDisplaySerializer(EventSerializer):
93 challenges = ChallengeSerializer(many=True, read_only=True)
94 teams = serializers.SerializerMethodField(read_only=True)
95 my_team = serializers.SerializerMethodField(read_only=True)
97 class Meta:
98 model = Event
99 fields = [
100 "random_slug",
101 "name",
102 "challenges",
103 "teams",
104 "date",
105 "my_team",
106 "is_master_of_ceremony",
107 ]
109 def get_teams(self, instance):
110 teams = instance.teams.all()
111 serializer = TeamScoreSerializer(teams, many=True)
112 data = serializer.data
113 return sorted(data, key=lambda item: item["total_score"], reverse=True)
115 def get_my_team(self, instance):
116 try:
117 participant = instance.participants.get(user=self.context.get("user"))
118 return participant.team.random_slug if participant.team else None
119 except Participant.DoesNotExist:
120 return None
123class EventDetailSerializer(EventDisplaySerializer):
124 participants = serializers.SerializerMethodField(read_only=True)
125 teams = TeamSerializer(many=True, read_only=True)
127 class Meta(EventDisplaySerializer.Meta):
128 fields = ["random_slug", "name", "challenges", "participants", "teams", "date"]
130 def get_participants(self, instance):
131 participants = instance.participants.filter(team__isnull=True)
132 serializer = ParticipantSerializer(participants, many=True)
133 return serializer.data
136class SimpleTeamSerializer(serializers.ModelSerializer):
137 class Meta:
138 model = Team
139 fields = ["random_slug", "name"]
140 read_only_fields = fields
143class StationCheckInDetailSerializer(serializers.ModelSerializer):
144 class Meta:
145 model = StationCheckIn
146 fields = ["team", "participant", "has_checkin", "updated_at"]
149class StationSerializer(serializers.ModelSerializer):
150 check_in = serializers.SerializerMethodField(read_only=True)
152 class Meta:
153 model = Station
154 fields = ["name", "hint", "check_in"]
156 def get_check_in(self, station):
157 user = self.context.get("user")
158 event = station.challenge.event
160 participant = user.participants.get(event=event)
161 team = participant.team
162 if team:
163 try:
164 check_in = team.check_ins.get(station=station)
165 return StationCheckInSerializer(check_in).data
166 except StationCheckIn.DoesNotExist:
167 return None
168 return None
171class ChallengeDetailSerializer(serializers.ModelSerializer):
172 event = EventSerializer(read_only=True)
173 finished = serializers.SerializerMethodField(read_only=True)
174 unfinished = serializers.SerializerMethodField(read_only=True)
175 teams_count = serializers.SerializerMethodField(read_only=True)
176 is_master_of_ceremony = serializers.SerializerMethodField(read_only=True)
177 stations = StationSerializer(many=True, read_only=True)
179 class Meta:
180 model = Challenge
181 fields = [
182 "random_slug",
183 "name",
184 "objective",
185 "event",
186 "is_master_of_ceremony",
187 "teams_count",
188 "finished",
189 "unfinished",
190 "type_of",
191 "status",
192 "stations",
193 ]
194 extra_kwargs = {"status": {"read_only": True}}
196 def get_finished(self, challenge):
197 scores = challenge.scores.order_by("position")
198 max_position = max([s.position for s in scores] + [0])
199 positions = []
200 for i in range(max_position):
201 positions.append({"teams": [], "points": None})
202 for s in scores:
203 team = SimpleTeamSerializer(s.team)
204 positions[s.position - 1]["teams"].append(team.data)
205 positions[s.position - 1]["points"] = s.score
206 return positions
208 def get_unfinished(self, challenge):
209 qs = challenge.event.teams.exclude(scores__challenge=challenge)
210 return SimpleTeamSerializer(qs, many=True).data
212 def get_teams_count(self, challenge):
213 return challenge.event.teams.count()
215 def get_is_master_of_ceremony(self, challenge):
216 participant = Participant.objects.get(
217 event=challenge.event, user=self.context.get("user")
218 )
219 return participant.is_master_of_ceremony
222class SaveScoresSerializer(serializers.Serializer):
223 challenge = serializers.CharField(write_only=True)
224 positions = serializers.ListField(write_only=True)
226 class Meta:
227 fields = ["challenge", "positions"]
229 def save(self, **kwargs):
230 challenge = Challenge.objects.get(
231 random_slug=self.validated_data.get("challenge")
232 )
234 slugs = []
235 position = 1
236 total_teams = challenge.event.teams.count()
237 scores = [i + 1 for i in range(total_teams)]
239 for item in self.validated_data.get("positions"):
240 score = [scores.pop() for i in range(len(item))]
241 for team in item:
242 random_slug = team.get("random_slug")
243 team = Team.objects.get(random_slug=random_slug)
244 Score.objects.update_or_create(
245 challenge=challenge,
246 team=team,
247 defaults={"position": position, "score": sum(score) / len(score)},
248 )
249 slugs.append(random_slug)
250 position += 1
252 challenge.scores.exclude(team__random_slug__in=slugs).delete()
254 # if challenge.scores.count() == total_teams and challenge.status == Challenge.Status.CURRENT:
255 # challenge.status = Challenge.Status.PAST
256 # challenge.save()
257 # next_challenge = challenge.next_challenge
258 # if next_challenge is not None:
259 # next_challenge.status = Challenge.Status.CURRENT
260 # next_challenge.save()
263class StationCheckInSerializer(serializers.ModelSerializer):
264 participant = serializers.SerializerMethodField(read_only=True)
265 date = serializers.SerializerMethodField(read_only=True)
266 time = serializers.SerializerMethodField(read_only=True)
268 class Meta:
269 model = StationCheckIn
270 fields = ["has_checkin", "date", "time", "participant"]
272 def get_participant(self, station):
273 if station.participant is not None:
274 return station.participant.user.name
276 def get_date(self, station):
277 return station.updated_at.strftime("%d/%m/%y")
279 def get_time(self, station):
280 return station.updated_at.strftime("%H:%M")