generated from bisco/codex-bootstrap
153 lines
6.2 KiB
Python
153 lines
6.2 KiB
Python
from django.conf import settings
|
|
from django.db import models
|
|
|
|
|
|
class UserProfile(models.Model):
|
|
ROLE_ADMIN = "admin"
|
|
ROLE_SCOUT = "scout"
|
|
ROLE_VIEWER = "viewer"
|
|
ROLE_CHOICES = [
|
|
(ROLE_ADMIN, "Admin"),
|
|
(ROLE_SCOUT, "Scout"),
|
|
(ROLE_VIEWER, "Viewer"),
|
|
]
|
|
|
|
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="profile")
|
|
role = models.CharField(max_length=16, choices=ROLE_CHOICES, default=ROLE_VIEWER)
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.user.username} ({self.role})"
|
|
|
|
|
|
class League(models.Model):
|
|
name = models.CharField(max_length=120)
|
|
code = models.CharField(max_length=16, unique=True)
|
|
region = models.CharField(max_length=60)
|
|
country = models.CharField(max_length=80)
|
|
|
|
class Meta:
|
|
ordering = ["region", "country", "name"]
|
|
|
|
def __str__(self) -> str:
|
|
return self.code
|
|
|
|
|
|
class Team(models.Model):
|
|
name = models.CharField(max_length=120)
|
|
league = models.ForeignKey(League, on_delete=models.PROTECT, related_name="teams")
|
|
country = models.CharField(max_length=80)
|
|
|
|
class Meta:
|
|
ordering = ["name"]
|
|
constraints = [models.UniqueConstraint(fields=["name", "league"], name="unique_team_per_league")]
|
|
|
|
def __str__(self) -> str:
|
|
return self.name
|
|
|
|
|
|
class Season(models.Model):
|
|
label = models.CharField(max_length=20, unique=True)
|
|
is_active = models.BooleanField(default=False)
|
|
|
|
class Meta:
|
|
ordering = ["-label"]
|
|
|
|
def __str__(self) -> str:
|
|
return self.label
|
|
|
|
|
|
class Player(models.Model):
|
|
POSITION_CHOICES = [
|
|
("PG", "Point Guard"),
|
|
("SG", "Shooting Guard"),
|
|
("SF", "Small Forward"),
|
|
("PF", "Power Forward"),
|
|
("C", "Center"),
|
|
]
|
|
|
|
first_name = models.CharField(max_length=80)
|
|
last_name = models.CharField(max_length=80)
|
|
position = models.CharField(max_length=2, choices=POSITION_CHOICES)
|
|
role = models.CharField(max_length=120, blank=True)
|
|
birth_year = models.PositiveSmallIntegerField(null=True, blank=True)
|
|
height_cm = models.PositiveSmallIntegerField(null=True, blank=True)
|
|
weight_kg = models.PositiveSmallIntegerField(null=True, blank=True)
|
|
nationality = models.CharField(max_length=80, blank=True)
|
|
current_team = models.ForeignKey(Team, on_delete=models.SET_NULL, null=True, blank=True, related_name="players")
|
|
external_source = models.CharField(max_length=80, blank=True)
|
|
external_id = models.CharField(max_length=120, blank=True)
|
|
profile_url = models.URLField(blank=True)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
class Meta:
|
|
ordering = ["last_name", "first_name"]
|
|
constraints = [
|
|
models.UniqueConstraint(
|
|
fields=["first_name", "last_name", "birth_year", "nationality"],
|
|
name="unique_player_identity",
|
|
)
|
|
]
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return f"{self.first_name} {self.last_name}"
|
|
|
|
def __str__(self) -> str:
|
|
return self.name
|
|
|
|
|
|
class PlayerSeasonStat(models.Model):
|
|
player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="season_stats")
|
|
team = models.ForeignKey(Team, on_delete=models.PROTECT, related_name="season_stats")
|
|
league = models.ForeignKey(League, on_delete=models.PROTECT, related_name="season_stats")
|
|
season = models.ForeignKey(Season, on_delete=models.PROTECT, related_name="player_stats")
|
|
games_played = models.PositiveSmallIntegerField(default=0)
|
|
minutes_per_game = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
points_per_game = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
assists_per_game = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
rebounds_per_game = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
steals_per_game = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
blocks_per_game = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
turnovers_per_game = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
field_goal_percentage = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
three_point_percentage = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
free_throw_percentage = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
efficiency_rating = models.DecimalField(max_digits=6, decimal_places=2, default=0)
|
|
true_shooting_percentage = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
usage_percentage = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
total_points = models.PositiveSmallIntegerField(default=0)
|
|
total_assists = models.PositiveSmallIntegerField(default=0)
|
|
total_rebounds = models.PositiveSmallIntegerField(default=0)
|
|
|
|
class Meta:
|
|
ordering = ["-efficiency_rating", "-points_per_game"]
|
|
constraints = [
|
|
models.UniqueConstraint(fields=["player", "team", "league", "season"], name="unique_player_stat_line")
|
|
]
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.player} {self.season} {self.league}"
|
|
|
|
|
|
class PlayerGameLog(models.Model):
|
|
player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="game_logs")
|
|
team = models.ForeignKey(Team, on_delete=models.PROTECT, related_name="game_logs")
|
|
opponent = models.CharField(max_length=120)
|
|
league = models.ForeignKey(League, on_delete=models.PROTECT, related_name="game_logs")
|
|
season = models.ForeignKey(Season, on_delete=models.PROTECT, related_name="game_logs")
|
|
game_date = models.DateField()
|
|
points = models.PositiveSmallIntegerField(default=0)
|
|
assists = models.PositiveSmallIntegerField(default=0)
|
|
rebounds = models.PositiveSmallIntegerField(default=0)
|
|
steals = models.PositiveSmallIntegerField(default=0)
|
|
blocks = models.PositiveSmallIntegerField(default=0)
|
|
turnovers = models.PositiveSmallIntegerField(default=0)
|
|
efficiency_rating = models.DecimalField(max_digits=6, decimal_places=2, default=0)
|
|
|
|
class Meta:
|
|
ordering = ["-game_date"]
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.player} vs {self.opponent} on {self.game_date}"
|