149 lines
5.5 KiB
Python
149 lines
5.5 KiB
Python
from __future__ import annotations
|
|
|
|
from django.db.models import Exists, OuterRef, Prefetch
|
|
from django.shortcuts import get_object_or_404, render
|
|
|
|
from .forms import PlayerSearchForm
|
|
from .models import Player, PlayerSeason
|
|
|
|
|
|
def player_list(request):
|
|
form = PlayerSearchForm(request.GET or None)
|
|
queryset = (
|
|
Player.objects.all()
|
|
.prefetch_related("roles", "specialties")
|
|
.order_by("full_name")
|
|
)
|
|
|
|
if form.is_valid():
|
|
data = form.cleaned_data
|
|
|
|
if data["name"]:
|
|
queryset = queryset.filter(full_name__icontains=data["name"])
|
|
if data["position"]:
|
|
queryset = queryset.filter(position=data["position"])
|
|
if data["role"]:
|
|
queryset = queryset.filter(roles=data["role"])
|
|
if data["specialty"]:
|
|
queryset = queryset.filter(specialties=data["specialty"])
|
|
|
|
if data["min_height_cm"] is not None:
|
|
queryset = queryset.filter(height_cm__gte=data["min_height_cm"])
|
|
if data["max_height_cm"] is not None:
|
|
queryset = queryset.filter(height_cm__lte=data["max_height_cm"])
|
|
if data["min_weight_kg"] is not None:
|
|
queryset = queryset.filter(weight_kg__gte=data["min_weight_kg"])
|
|
if data["max_weight_kg"] is not None:
|
|
queryset = queryset.filter(weight_kg__lte=data["max_weight_kg"])
|
|
|
|
if data["min_age"] is not None:
|
|
cutoff = form.birth_date_upper_bound_for_age(data["min_age"])
|
|
queryset = queryset.filter(birth_date__lte=cutoff)
|
|
if data["max_age"] is not None:
|
|
cutoff = form.birth_date_lower_bound_for_age(data["max_age"])
|
|
queryset = queryset.filter(birth_date__gte=cutoff)
|
|
|
|
context_filters_used = any(
|
|
data[field] is not None and data[field] != ""
|
|
for field in [
|
|
"competition",
|
|
"season",
|
|
"team",
|
|
"min_points",
|
|
"min_assists",
|
|
"min_steals",
|
|
"max_turnovers",
|
|
"min_blocks",
|
|
"min_efg_pct",
|
|
"min_ts_pct",
|
|
"min_plus_minus",
|
|
"min_offensive_rating",
|
|
"max_defensive_rating",
|
|
]
|
|
)
|
|
|
|
if context_filters_used:
|
|
context_qs = PlayerSeason.objects.filter(player=OuterRef("pk"))
|
|
|
|
if data["competition"]:
|
|
context_qs = context_qs.filter(competition=data["competition"])
|
|
if data["season"]:
|
|
context_qs = context_qs.filter(season=data["season"])
|
|
if data["team"]:
|
|
context_qs = context_qs.filter(team=data["team"])
|
|
|
|
stats_filters_used = any(
|
|
data[field] is not None
|
|
for field in [
|
|
"min_points",
|
|
"min_assists",
|
|
"min_steals",
|
|
"max_turnovers",
|
|
"min_blocks",
|
|
"min_efg_pct",
|
|
"min_ts_pct",
|
|
"min_plus_minus",
|
|
"min_offensive_rating",
|
|
"max_defensive_rating",
|
|
]
|
|
)
|
|
if stats_filters_used:
|
|
context_qs = context_qs.filter(stats__isnull=False)
|
|
|
|
if data["min_points"] is not None:
|
|
context_qs = context_qs.filter(stats__points__gte=data["min_points"])
|
|
if data["min_assists"] is not None:
|
|
context_qs = context_qs.filter(stats__assists__gte=data["min_assists"])
|
|
if data["min_steals"] is not None:
|
|
context_qs = context_qs.filter(stats__steals__gte=data["min_steals"])
|
|
if data["max_turnovers"] is not None:
|
|
context_qs = context_qs.filter(stats__turnovers__lte=data["max_turnovers"])
|
|
if data["min_blocks"] is not None:
|
|
context_qs = context_qs.filter(stats__blocks__gte=data["min_blocks"])
|
|
if data["min_efg_pct"] is not None:
|
|
context_qs = context_qs.filter(stats__efg_pct__gte=data["min_efg_pct"])
|
|
if data["min_ts_pct"] is not None:
|
|
context_qs = context_qs.filter(stats__ts_pct__gte=data["min_ts_pct"])
|
|
if data["min_plus_minus"] is not None:
|
|
context_qs = context_qs.filter(stats__plus_minus__gte=data["min_plus_minus"])
|
|
if data["min_offensive_rating"] is not None:
|
|
context_qs = context_qs.filter(stats__offensive_rating__gte=data["min_offensive_rating"])
|
|
if data["max_defensive_rating"] is not None:
|
|
context_qs = context_qs.filter(stats__defensive_rating__lte=data["max_defensive_rating"])
|
|
|
|
queryset = queryset.annotate(has_matching_context=Exists(context_qs)).filter(has_matching_context=True)
|
|
|
|
queryset = queryset.distinct()
|
|
|
|
return render(
|
|
request,
|
|
"scouting/player_list.html",
|
|
{
|
|
"form": form,
|
|
"players": queryset,
|
|
},
|
|
)
|
|
|
|
|
|
def player_detail(request, player_id: int):
|
|
player = get_object_or_404(
|
|
Player.objects.prefetch_related("roles", "specialties"),
|
|
pk=player_id,
|
|
)
|
|
|
|
contexts = (
|
|
PlayerSeason.objects.filter(player=player)
|
|
.select_related("season", "team", "competition")
|
|
.prefetch_related(Prefetch("stats"))
|
|
.order_by("-season__start_year", "team__name", "competition__name")
|
|
)
|
|
|
|
return render(
|
|
request,
|
|
"scouting/player_detail.html",
|
|
{
|
|
"player": player,
|
|
"contexts": contexts,
|
|
},
|
|
)
|