phase4: implement player search filters, htmx results, and detail page
This commit is contained in:
@ -1,5 +1,125 @@
|
||||
from django.views.generic import TemplateView
|
||||
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
|
||||
|
||||
|
||||
class PlayersHomeView(TemplateView):
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user