from datetime import date from django.db.models import Prefetch from django.views.generic import DetailView, ListView from apps.stats.models import PlayerSeason from .forms import PlayerSearchForm from .models import Player from .services.search import apply_sorting, base_player_queryset, filter_players def calculate_age(birth_date): if not birth_date: return None today = date.today() return today.year - birth_date.year - ( (today.month, today.day) < (birth_date.month, birth_date.day) ) class PlayerSearchView(ListView): model = Player context_object_name = "players" paginate_by = 20 template_name = "players/index.html" def get_template_names(self): if self.request.headers.get("HX-Request") == "true": return ["players/partials/results.html"] return [self.template_name] def get_form(self): if not hasattr(self, "_search_form"): self._search_form = PlayerSearchForm(self.request.GET or None) return self._search_form def get_paginate_by(self, queryset): form = self.get_form() if form.is_valid(): return form.cleaned_data.get("page_size") or 20 return self.paginate_by def get_queryset(self): form = self.get_form() queryset = base_player_queryset() if form.is_valid(): queryset = filter_players(queryset, form.cleaned_data) queryset = apply_sorting(queryset, form.cleaned_data.get("sort", "name_asc")) else: queryset = queryset.order_by("full_name", "id") return queryset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["search_form"] = self.get_form() return context class PlayerDetailView(DetailView): model = Player template_name = "players/detail.html" context_object_name = "player" def get_queryset(self): season_queryset = PlayerSeason.objects.select_related( "season", "team", "competition", "stats", ).order_by("-season__start_date", "-id") return ( Player.objects.select_related( "nationality", "nominal_position", "inferred_role", ) .prefetch_related( "aliases", Prefetch("player_seasons", queryset=season_queryset), "career_entries__team", "career_entries__competition", "career_entries__season", "career_entries__role_snapshot", ) ) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) player = self.object raw_season_rows = list(player.player_seasons.all()) current_assignment = next( (row for row in raw_season_rows if row.season and row.season.is_current), None, ) if current_assignment is None and raw_season_rows: current_assignment = raw_season_rows[0] season_rows = [] for row in raw_season_rows: try: stats = row.stats except PlayerSeason.stats.RelatedObjectDoesNotExist: stats = None season_rows.append( { "season": row.season, "team": row.team, "competition": row.competition, "games_played": row.games_played, "minutes_played": row.minutes_played, "mpg": (row.minutes_played / row.games_played) if row.games_played else None, "stats": stats, } ) context["age"] = calculate_age(player.birth_date) context["current_assignment"] = current_assignment context["career_entries"] = player.career_entries.all().order_by("-start_date", "-id") context["season_rows"] = season_rows return context