phase7: add minimal read-only drf api with player search endpoints
This commit is contained in:
151
apps/api/serializers.py
Normal file
151
apps/api/serializers.py
Normal file
@ -0,0 +1,151 @@
|
||||
from datetime import date
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from apps.competitions.models import Competition, Season
|
||||
from apps.players.models import Player
|
||||
from apps.stats.models import PlayerSeason
|
||||
from apps.teams.models import Team
|
||||
|
||||
|
||||
class CompetitionSerializer(serializers.ModelSerializer):
|
||||
country = serializers.CharField(source="country.name", allow_null=True)
|
||||
|
||||
class Meta:
|
||||
model = Competition
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
"slug",
|
||||
"competition_type",
|
||||
"gender",
|
||||
"level",
|
||||
"country",
|
||||
"is_active",
|
||||
]
|
||||
|
||||
|
||||
class TeamSerializer(serializers.ModelSerializer):
|
||||
country = serializers.CharField(source="country.name", allow_null=True)
|
||||
|
||||
class Meta:
|
||||
model = Team
|
||||
fields = ["id", "name", "short_name", "slug", "country", "is_national_team"]
|
||||
|
||||
|
||||
class SeasonSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Season
|
||||
fields = ["id", "label", "start_date", "end_date", "is_current"]
|
||||
|
||||
|
||||
class PlayerListSerializer(serializers.ModelSerializer):
|
||||
nationality = serializers.CharField(source="nationality.name", allow_null=True)
|
||||
nominal_position = serializers.CharField(source="nominal_position.code", allow_null=True)
|
||||
inferred_role = serializers.CharField(source="inferred_role.name", allow_null=True)
|
||||
|
||||
class Meta:
|
||||
model = Player
|
||||
fields = [
|
||||
"id",
|
||||
"full_name",
|
||||
"birth_date",
|
||||
"nationality",
|
||||
"nominal_position",
|
||||
"inferred_role",
|
||||
"height_cm",
|
||||
"weight_kg",
|
||||
"dominant_hand",
|
||||
"is_active",
|
||||
]
|
||||
|
||||
|
||||
class PlayerAliasSerializer(serializers.Serializer):
|
||||
alias = serializers.CharField()
|
||||
source = serializers.CharField(allow_blank=True)
|
||||
is_primary = serializers.BooleanField()
|
||||
|
||||
|
||||
class PlayerSeasonStatSerializer(serializers.Serializer):
|
||||
season = serializers.CharField(allow_null=True)
|
||||
team = serializers.CharField(allow_null=True)
|
||||
competition = serializers.CharField(allow_null=True)
|
||||
games_played = serializers.IntegerField()
|
||||
minutes_played = serializers.IntegerField()
|
||||
points = serializers.DecimalField(max_digits=6, decimal_places=2, allow_null=True)
|
||||
rebounds = serializers.DecimalField(max_digits=6, decimal_places=2, allow_null=True)
|
||||
assists = serializers.DecimalField(max_digits=6, decimal_places=2, allow_null=True)
|
||||
steals = serializers.DecimalField(max_digits=6, decimal_places=2, allow_null=True)
|
||||
blocks = serializers.DecimalField(max_digits=6, decimal_places=2, allow_null=True)
|
||||
turnovers = serializers.DecimalField(max_digits=6, decimal_places=2, allow_null=True)
|
||||
fg_pct = serializers.DecimalField(max_digits=5, decimal_places=2, allow_null=True)
|
||||
three_pct = serializers.DecimalField(max_digits=5, decimal_places=2, allow_null=True)
|
||||
ft_pct = serializers.DecimalField(max_digits=5, decimal_places=2, allow_null=True)
|
||||
player_efficiency_rating = serializers.DecimalField(max_digits=6, decimal_places=2, allow_null=True)
|
||||
|
||||
|
||||
class PlayerDetailSerializer(serializers.ModelSerializer):
|
||||
nationality = serializers.CharField(source="nationality.name", allow_null=True)
|
||||
nominal_position = serializers.CharField(source="nominal_position.name", allow_null=True)
|
||||
inferred_role = serializers.CharField(source="inferred_role.name", allow_null=True)
|
||||
age = serializers.SerializerMethodField()
|
||||
aliases = serializers.SerializerMethodField()
|
||||
season_stats = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Player
|
||||
fields = [
|
||||
"id",
|
||||
"full_name",
|
||||
"birth_date",
|
||||
"age",
|
||||
"nationality",
|
||||
"nominal_position",
|
||||
"inferred_role",
|
||||
"height_cm",
|
||||
"weight_kg",
|
||||
"dominant_hand",
|
||||
"aliases",
|
||||
"season_stats",
|
||||
]
|
||||
|
||||
def get_age(self, obj):
|
||||
if not obj.birth_date:
|
||||
return None
|
||||
today = date.today()
|
||||
return today.year - obj.birth_date.year - (
|
||||
(today.month, today.day) < (obj.birth_date.month, obj.birth_date.day)
|
||||
)
|
||||
|
||||
def get_aliases(self, obj):
|
||||
return PlayerAliasSerializer(obj.aliases.all(), many=True).data
|
||||
|
||||
def get_season_stats(self, obj):
|
||||
rows = (
|
||||
PlayerSeason.objects.filter(player=obj)
|
||||
.select_related("season", "team", "competition", "stats")
|
||||
.order_by("-season__start_date", "-id")
|
||||
)
|
||||
payload = []
|
||||
for row in rows:
|
||||
stats = getattr(row, "stats", None)
|
||||
payload.append(
|
||||
{
|
||||
"season": row.season.label if row.season else None,
|
||||
"team": row.team.name if row.team else None,
|
||||
"competition": row.competition.name if row.competition else None,
|
||||
"games_played": row.games_played,
|
||||
"minutes_played": row.minutes_played,
|
||||
"points": getattr(stats, "points", None),
|
||||
"rebounds": getattr(stats, "rebounds", None),
|
||||
"assists": getattr(stats, "assists", None),
|
||||
"steals": getattr(stats, "steals", None),
|
||||
"blocks": getattr(stats, "blocks", None),
|
||||
"turnovers": getattr(stats, "turnovers", None),
|
||||
"fg_pct": getattr(stats, "fg_pct", None),
|
||||
"three_pct": getattr(stats, "three_pct", None),
|
||||
"ft_pct": getattr(stats, "ft_pct", None),
|
||||
"player_efficiency_rating": getattr(stats, "player_efficiency_rating", None),
|
||||
}
|
||||
)
|
||||
return PlayerSeasonStatSerializer(payload, many=True).data
|
||||
Reference in New Issue
Block a user