Align balldontlie OpenAPI integration and clarify search metric semantics
This commit is contained in:
@ -13,10 +13,10 @@ class PlayerSearchForm(forms.Form):
|
||||
("age_oldest", "Age (Oldest first)"),
|
||||
("height_desc", "Height (Tallest first)"),
|
||||
("height_asc", "Height (Shortest first)"),
|
||||
("ppg_desc", "Points per game (High to low)"),
|
||||
("ppg_asc", "Points per game (Low to high)"),
|
||||
("mpg_desc", "Minutes per game (High to low)"),
|
||||
("mpg_asc", "Minutes per game (Low to high)"),
|
||||
("ppg_desc", "Best eligible PPG (High to low)"),
|
||||
("ppg_asc", "Best eligible PPG (Low to high)"),
|
||||
("mpg_desc", "Best eligible MPG (High to low)"),
|
||||
("mpg_asc", "Best eligible MPG (Low to high)"),
|
||||
)
|
||||
|
||||
PAGE_SIZE_CHOICES = ((20, "20"), (50, "50"), (100, "100"))
|
||||
|
||||
@ -20,6 +20,10 @@ from apps.players.models import Player
|
||||
from apps.stats.models import PlayerSeason
|
||||
|
||||
METRIC_SORT_KEYS = {"ppg_desc", "ppg_asc", "mpg_desc", "mpg_asc"}
|
||||
SEARCH_METRIC_SEMANTICS_TEXT = (
|
||||
"Search metrics are best eligible values per player (max per metric across eligible player-season rows). "
|
||||
"With season/team/competition/stat filters, eligibility is scoped by those filters."
|
||||
)
|
||||
|
||||
|
||||
def _years_ago_today(years: int) -> date:
|
||||
@ -213,6 +217,13 @@ def filter_players(queryset, data: dict):
|
||||
|
||||
|
||||
def annotate_player_metrics(queryset, data: dict | None = None):
|
||||
"""
|
||||
Annotate player list metrics using best-eligible semantics.
|
||||
|
||||
Each metric is computed as MAX over eligible player-season rows. This is intentionally
|
||||
not a single-row projection; different displayed metrics for one player can come from
|
||||
different eligible player-season rows.
|
||||
"""
|
||||
data = data or {}
|
||||
context_filter = _build_metric_context_filter(data)
|
||||
|
||||
|
||||
@ -8,7 +8,13 @@ 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
|
||||
from .services.search import (
|
||||
SEARCH_METRIC_SEMANTICS_TEXT,
|
||||
annotate_player_metrics,
|
||||
apply_sorting,
|
||||
base_player_queryset,
|
||||
filter_players,
|
||||
)
|
||||
|
||||
|
||||
def calculate_age(birth_date):
|
||||
@ -61,6 +67,7 @@ class PlayerSearchView(ListView):
|
||||
search_form = self.get_form()
|
||||
context["search_form"] = search_form
|
||||
context["search_has_errors"] = search_form.is_bound and bool(search_form.errors)
|
||||
context["search_metric_semantics"] = SEARCH_METRIC_SEMANTICS_TEXT
|
||||
context["favorite_player_ids"] = set()
|
||||
if self.request.user.is_authenticated:
|
||||
player_ids = [player.id for player in context["players"]]
|
||||
|
||||
Reference in New Issue
Block a user