Improve search quality, ORM efficiency, and filter consistency
This commit is contained in:
@ -16,6 +16,8 @@ from django.db.models.functions import Coalesce
|
||||
|
||||
from apps.players.models import Player
|
||||
|
||||
METRIC_SORT_KEYS = {"ppg_desc", "ppg_asc", "mpg_desc", "mpg_asc"}
|
||||
|
||||
|
||||
def _years_ago_today(years: int) -> date:
|
||||
today = date.today()
|
||||
@ -36,6 +38,40 @@ def _apply_min_max_filter(queryset, min_key: str, max_key: str, field_name: str,
|
||||
return queryset
|
||||
|
||||
|
||||
def _needs_distinct(data: dict) -> bool:
|
||||
join_filter_keys = (
|
||||
"q",
|
||||
"team",
|
||||
"competition",
|
||||
"season",
|
||||
"games_played_min",
|
||||
"games_played_max",
|
||||
"minutes_per_game_min",
|
||||
"minutes_per_game_max",
|
||||
"points_per_game_min",
|
||||
"points_per_game_max",
|
||||
"rebounds_per_game_min",
|
||||
"rebounds_per_game_max",
|
||||
"assists_per_game_min",
|
||||
"assists_per_game_max",
|
||||
"steals_per_game_min",
|
||||
"steals_per_game_max",
|
||||
"blocks_per_game_min",
|
||||
"blocks_per_game_max",
|
||||
"turnovers_per_game_min",
|
||||
"turnovers_per_game_max",
|
||||
"fg_pct_min",
|
||||
"fg_pct_max",
|
||||
"three_pct_min",
|
||||
"three_pct_max",
|
||||
"ft_pct_min",
|
||||
"ft_pct_max",
|
||||
"efficiency_metric_min",
|
||||
"efficiency_metric_max",
|
||||
)
|
||||
return any(data.get(key) not in (None, "") for key in join_filter_keys)
|
||||
|
||||
|
||||
def filter_players(queryset, data: dict):
|
||||
query = data.get("q")
|
||||
if query:
|
||||
@ -108,6 +144,12 @@ def filter_players(queryset, data: dict):
|
||||
for min_key, max_key, field_name in stat_pairs:
|
||||
queryset = _apply_min_max_filter(queryset, min_key, max_key, field_name, data)
|
||||
|
||||
if _needs_distinct(data):
|
||||
return queryset.distinct()
|
||||
return queryset
|
||||
|
||||
|
||||
def annotate_player_metrics(queryset):
|
||||
mpg_expression = Case(
|
||||
When(
|
||||
player_seasons__games_played__gt=0,
|
||||
@ -120,7 +162,7 @@ def filter_players(queryset, data: dict):
|
||||
output_field=FloatField(),
|
||||
)
|
||||
|
||||
queryset = queryset.annotate(
|
||||
return queryset.annotate(
|
||||
games_played_value=Coalesce(
|
||||
Max("player_seasons__games_played"),
|
||||
Value(0, output_field=IntegerField()),
|
||||
@ -159,8 +201,6 @@ def filter_players(queryset, data: dict):
|
||||
),
|
||||
)
|
||||
|
||||
return queryset.distinct()
|
||||
|
||||
|
||||
def apply_sorting(queryset, sort_key: str):
|
||||
if sort_key == "name_desc":
|
||||
@ -191,4 +231,4 @@ def base_player_queryset():
|
||||
"inferred_role",
|
||||
"origin_competition",
|
||||
"origin_team",
|
||||
).prefetch_related("aliases")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user