Files
hoopscout-v3/backend/scouting/management/commands/seed_demo_data.py
T

253 lines
10 KiB
Python

from django.core.management.base import BaseCommand
from scouting.models import League, Player, PlayerGameLog, PlayerSeasonStat, Season, Team
class Command(BaseCommand):
help = "Seed synthetic European scouting data for local development."
def handle(self, *args, **options):
season, _ = Season.objects.update_or_create(label="2025-26", defaults={"is_active": True})
leagues = {
"LBA": League.objects.update_or_create(
code="LBA",
defaults={"name": "Lega Basket Serie A", "region": "Europe", "country": "Italy"},
)[0],
"ACB": League.objects.update_or_create(
code="ACB",
defaults={"name": "Liga Endesa", "region": "Europe", "country": "Spain"},
)[0],
"ABA": League.objects.update_or_create(
code="ABA",
defaults={"name": "ABA League", "region": "Europe", "country": "Adriatic"},
)[0],
"BBL": League.objects.update_or_create(
code="BBL",
defaults={"name": "Basketball Bundesliga", "region": "Europe", "country": "Germany"},
)[0],
"BSL": League.objects.update_or_create(
code="BSL",
defaults={"name": "Basketbol Super Ligi", "region": "Europe", "country": "Turkey"},
)[0],
"LNB": League.objects.update_or_create(
code="LNB",
defaults={"name": "LNB Elite", "region": "Europe", "country": "France"},
)[0],
"ISBL": League.objects.update_or_create(
code="ISBL",
defaults={"name": "Israeli Basketball Premier League", "region": "Europe", "country": "Israel"},
)[0],
"NBL": League.objects.update_or_create(
code="NBL",
defaults={"name": "National Basketball League", "region": "Oceania", "country": "Australia"},
)[0],
"NZNBL": League.objects.update_or_create(
code="NZNBL",
defaults={"name": "New Zealand NBL", "region": "Oceania", "country": "New Zealand"},
)[0],
}
demo_rows = [
(
"Luca", "Marini", "PG", "Primary ball handler", 2001, 190, 86, "Italy",
"Milano", "LBA", 16.8, 6.2, 3.8, 20.5, 59.2, 25.0,
),
(
"Davide", "Rossi", "SG", "Movement shooter", 2002, 195, 88, "Italy",
"Bologna", "LBA", 14.6, 2.4, 3.1, 15.8, 61.0, 21.4,
),
(
"Nikola", "Petrovic", "PF", "Stretch four", 1998, 206, 103, "Serbia",
"Trieste", "LBA", 12.9, 2.7, 6.8, 17.2, 58.4, 18.8,
),
(
"Mateo", "Santos", "SF", "3 and D wing", 1999, 201, 96, "Spain",
"Madrid", "ACB", 11.2, 2.1, 5.5, 13.7, 55.8, 17.5,
),
(
"Iker", "Varela", "PG", "Tempo guard", 2000, 188, 82, "Spain",
"Valencia", "ACB", 13.8, 5.9, 2.9, 18.1, 57.3, 23.7,
),
(
"Moussa", "Diagne", "C", "Rim protector", 1997, 213, 111, "Senegal",
"Malaga", "ACB", 9.7, 1.1, 8.9, 16.4, 64.8, 15.2,
),
(
"Marko", "Ilic", "PG", "Pick and roll creator", 2001, 192, 87, "Serbia",
"Belgrade", "ABA", 15.1, 6.8, 3.3, 19.6, 56.6, 26.1,
),
(
"Luka", "Horvat", "SF", "Slashing wing", 1999, 202, 94, "Croatia",
"Zadar", "ABA", 13.4, 2.8, 5.9, 16.0, 55.1, 20.5,
),
(
"Amar", "Kovac", "C", "Low-post finisher", 1998, 210, 114, "Bosnia",
"Ljubljana", "ABA", 11.8, 1.6, 7.7, 15.5, 60.9, 18.0,
),
(
"Jonas", "Keller", "C", "Roll man", 2000, 211, 109, "Germany",
"Berlin", "BBL", 13.1, 1.4, 8.6, 18.9, 63.1, 19.0,
),
(
"Tobias", "Weber", "SG", "Secondary creator", 2002, 196, 91, "Germany",
"Munich", "BBL", 15.9, 3.7, 4.2, 17.8, 58.0, 22.9,
),
(
"Leon", "Schmidt", "PF", "Short-roll passer", 1999, 205, 101, "Germany",
"Ulm", "BBL", 10.6, 3.2, 6.4, 14.9, 56.7, 16.8,
),
(
"Emir", "Yilmaz", "PG", "Pressure guard", 2001, 189, 84, "Turkey",
"Istanbul", "BSL", 17.4, 5.5, 3.0, 20.1, 57.8, 27.2,
),
(
"Can", "Demir", "SF", "Transition wing", 2000, 200, 95, "Turkey",
"Ankara", "BSL", 12.7, 2.5, 5.1, 14.4, 54.6, 19.4,
),
(
"Kerem", "Arslan", "C", "Paint anchor", 1998, 212, 116, "Turkey",
"Izmir", "BSL", 10.2, 1.2, 9.3, 17.0, 62.3, 14.8,
),
(
"Noam", "Levi", "SG", "Pull-up shooter", 2002, 194, 88, "Israel",
"Tel Aviv", "ISBL", 16.1, 3.0, 3.5, 16.9, 59.5, 24.1,
),
(
"Amit", "Cohen", "PG", "Drive and kick guard", 2001, 187, 81, "Israel",
"Jerusalem", "ISBL", 14.2, 6.4, 2.7, 18.7, 56.9, 25.5,
),
(
"Eitan", "Mizrahi", "PF", "Switch defender", 1999, 204, 100, "Israel",
"Holon", "ISBL", 9.8, 2.0, 7.1, 13.9, 54.2, 15.7,
),
(
"Theo", "Moreau", "PG", "Change-of-pace guard", 2003, 186, 80, "France",
"Paris", "LNB", 12.5, 5.8, 2.5, 16.8, 55.5, 22.2,
),
(
"Bastien", "Girard", "SF", "Connector wing", 2000, 199, 92, "France",
"Monaco", "LNB", 10.9, 3.6, 4.8, 14.6, 57.1, 16.3,
),
(
"Yanis", "Traore", "C", "Vertical spacer", 2001, 214, 112, "France",
"Lyon", "LNB", 11.4, 1.0, 8.1, 16.7, 65.0, 15.0,
),
(
"Jayden", "Mills", "SG", "Off-screen scorer", 2000, 197, 92, "Australia",
"Sydney", "NBL", 18.2, 2.9, 4.0, 19.4, 60.1, 26.4,
),
(
"Cooper", "Reed", "PF", "Face-up forward", 1999, 206, 102, "Australia",
"Melbourne", "NBL", 13.6, 2.4, 7.3, 17.5, 58.6, 20.0,
),
(
"Hemi", "Walker", "PG", "Paint touch guard", 2002, 191, 85, "New Zealand",
"Auckland", "NZNBL", 15.7, 7.1, 3.9, 21.2, 57.5, 27.0,
),
(
"Tane", "Rangi", "SF", "Defensive playmaker", 2001, 203, 98, "New Zealand",
"Wellington", "NZNBL", 11.6, 3.4, 6.5, 15.9, 55.4, 18.7,
),
(
"Finn", "McKenzie", "C", "Glass cleaner", 1998, 211, 113, "New Zealand",
"Canterbury", "NZNBL", 9.4, 1.3, 10.2, 16.1, 61.8, 13.9,
),
]
for row in demo_rows:
(
first_name,
last_name,
position,
role,
birth_year,
height_cm,
weight_kg,
nationality,
team_name,
league_code,
points,
assists,
rebounds,
efficiency,
true_shooting,
usage,
) = row
games_played = 28
minutes = round(18 + usage * 0.42, 2)
league = leagues[league_code]
team, _ = Team.objects.update_or_create(
name=team_name,
league=league,
defaults={"country": league.country},
)
player, _ = Player.objects.update_or_create(
first_name=first_name,
last_name=last_name,
birth_year=birth_year,
nationality=nationality,
defaults={
"position": position,
"role": role,
"height_cm": height_cm,
"weight_kg": weight_kg,
"current_team": team,
"external_source": "synthetic",
},
)
PlayerSeasonStat.objects.update_or_create(
player=player,
team=team,
league=league,
season=season,
defaults={
"games_played": games_played,
"minutes_per_game": minutes,
"points_per_game": points,
"assists_per_game": assists,
"rebounds_per_game": rebounds,
"steals_per_game": 0.7 + (assists / 10),
"blocks_per_game": 0.2 + (rebounds / 18),
"turnovers_per_game": 1.0 + (usage / 20),
"field_goal_percentage": 42.5 + (true_shooting / 5),
"three_point_percentage": 28.0 + (points / 2.3),
"free_throw_percentage": 70.0 + (usage / 2),
"efficiency_rating": efficiency,
"true_shooting_percentage": true_shooting,
"usage_percentage": usage,
"total_points": int(points * games_played),
"total_assists": int(assists * games_played),
"total_rebounds": int(rebounds * games_played),
},
)
PlayerGameLog.objects.update_or_create(
player=player,
team=team,
league=league,
season=season,
game_date="2026-01-10",
opponent="Top domestic opponent",
defaults={
"points": int(points + 10),
"assists": int(assists + 3),
"rebounds": int(rebounds + 2),
"efficiency_rating": efficiency + 10,
},
)
PlayerGameLog.objects.update_or_create(
player=player,
team=team,
league=league,
season=season,
game_date="2026-01-17",
opponent="Physical road opponent",
defaults={
"points": max(0, int(points - 7)),
"assists": max(0, int(assists - 2)),
"rebounds": max(0, int(rebounds - 3)),
"efficiency_rating": max(0, efficiency - 9),
},
)
self.stdout.write(self.style.SUCCESS("Seeded synthetic HoopScout demo data."))