148 lines
4.9 KiB
Python
148 lines
4.9 KiB
Python
from datetime import date
|
|
|
|
from django.db.models import Prefetch
|
|
from django.views.generic import DetailView, ListView
|
|
|
|
from apps.scouting.models import FavoritePlayer
|
|
from apps.stats.models import PlayerSeason
|
|
|
|
from .forms import PlayerSearchForm
|
|
from .models import Player, PlayerCareerEntry
|
|
from .services.search import annotate_player_metrics, 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 = annotate_player_metrics(queryset)
|
|
queryset = apply_sorting(queryset, form.cleaned_data.get("sort", "name_asc"))
|
|
else:
|
|
queryset = annotate_player_metrics(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()
|
|
context["favorite_player_ids"] = set()
|
|
if self.request.user.is_authenticated:
|
|
player_ids = [player.id for player in context["players"]]
|
|
context["favorite_player_ids"] = set(
|
|
FavoritePlayer.objects.filter(
|
|
user=self.request.user,
|
|
player_id__in=player_ids,
|
|
).values_list("player_id", flat=True)
|
|
)
|
|
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")
|
|
career_queryset = PlayerCareerEntry.objects.select_related(
|
|
"team",
|
|
"competition",
|
|
"season",
|
|
"role_snapshot",
|
|
).order_by("-start_date", "-id")
|
|
|
|
return (
|
|
Player.objects.select_related(
|
|
"nationality",
|
|
"nominal_position",
|
|
"inferred_role",
|
|
"origin_competition",
|
|
"origin_team",
|
|
)
|
|
.prefetch_related(
|
|
"aliases",
|
|
Prefetch("player_seasons", queryset=season_queryset),
|
|
Prefetch("career_entries", queryset=career_queryset),
|
|
)
|
|
)
|
|
|
|
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()
|
|
context["season_rows"] = season_rows
|
|
context["is_favorite"] = False
|
|
if self.request.user.is_authenticated:
|
|
context["is_favorite"] = FavoritePlayer.objects.filter(
|
|
user=self.request.user,
|
|
player=player,
|
|
).exists()
|
|
return context
|