You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
6.7 KiB

from django.db import models
# Create your models here.
class Season(models.Model):
name = models.CharField(max_length=32, blank=False, null=False)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
class Division(models.Model):
name = models.CharField(max_length=64, blank=False, null=False)
class Team(models.Model):
name = models.CharField(max_length=32, blank=False, null=False)
season = models.ForeignKey(Season, related_name="teams", on_delete=models.PROTECT, blank=False, null=False)
division = models.ForeignKey(Division, related_name="teams", on_delete=models.PROTECT, blank=False, null=False)
class Player(models.Model):
first_name = models.CharField(max_length=32, blank=True, null=False)
last_name = models.CharField(max_length=32, blank=False, null=False)
middle_names = models.CharField(max_length=64, blank=True, null=False)
class TeamPlayer(models.Model):
team = models.ForeignKey(Team, related_name="players", on_delete=models.PROTECT, blank=False, null=False)
player = models.ForeignKey(Player, related_name="teams", on_delete=models.PROTECT, blank=False, null=False)
number = models.IntegerField(blank=False, null=False)
class Game(models.Model):
_name = models.CharField(max_length=64, blank=True, null=True)
home_team = models.ForeignKey(Team, related_name="home_games", on_delete=models.PROTECT, blank=True, null=True)
away_team = models.ForeignKey(Team, related_name="away_games", on_delete=models.PROTECT, blank=True, null=True)
season = models.ForeignKey(Season, related_name="games", on_delete=models.PROTECT, blank=False, null=False)
date_of = models.DateField(blank=False, null=False)
time_of = models.TimeField(blank=True, null=True)
def name(self):
return name if name else f"{home_team} v. {away_team}"
PERIOD_CHOICES = [
(1, "1st"),
(2, "2nd"),
(3, "3rd"),
(4, "OT"),
(5, "2OT"),
(6, "3OT"),
(7, "4OT"),
(8, "5OT"),
(9, "6OT"),
(0, "SO")
]
class Goal(models.Model):
scorer = models.ForeignKey(TeamPlayer, related_name="goals", on_delete=models.PROTECT, blank=False, null=False)
game = models.ForeignKey(Game, related_name="goals", on_delete=models.PROTECT, blank=False, null=False)
# NOTE: may be null if empty net
goalie = models.ForeignKey(TeamPlayer, related_name="goals_on", on_delete=models.PROTECT, blank=True, null=True)
assists = models.ManyToManyField(TeamPlayer, related_name="assists", blank=True)
period = models.IntegerField(choices=PERIOD_CHOICES, blank=False, null=False, default=1)
time = models.DurationField(blank=True, null=True)
# TODO allow no time column during SO
class Shot(models.Model):
SHOT_TYPE_CHOICES = [
("O", "On Goal"),
("M", "Missed"),
("B", "Blocked"),
]
# NOTE: default shot type is "on goal"
shot_type = models.CharField(max_length=1, choices=SHOT_TYPE_CHOICES, blank=False, null=False, default="O")
shooter = models.ForeignKey(TeamPlayer, related_name="shots", on_delete=models.PROTECT, blank=False, null=False)
game = models.ForeignKey(Game, related_name="shots", on_delete=models.PROTECT, blank=False, null=False)
period = models.IntegerField(choices=PERIOD_CHOICES, blank=False, null=False, default=1)
time = models.DurationField(blank=True, null=True)
# NOTE: the goalie the shot was on; note that only player.shots_on.filter(shot_type="O") count as saved goals
# NOTE: may be blank if an attempt is made on an open net
goalie = models.ForeignKey(TeamPlayer, related_name="shots_on", on_delete=models.PROTECT, blank=True, null=True)
# TODO allow no time column during SO
# this is only set in the case of a shot_type="B" for blocked
blocker = models.ForeignKey(TeamPlayer, related_name="blocked_shots", on_delete=models.PROTECT, blank=True, null=True)
# NOTE: game misconducts will eject a player from the game, but the penelty may be served by another player
class PeneltyLength(models.Model):
PENELTY_LENGTH_CHOICES = [
("M", "Minor"), # 2 mins in NHL
("MR", "Minor (running)"), # 3 minutes for running clock compensation
("D", "Double Minor"), # 4 mins in NHL
("J", "Major"), # 5 mins in NHL
("C", "Misconduct"), # 10 mins in NHL
("G", "Game Misconduct"), # ejection from game in NHL
("S", "Shot"), # penelty shot
]
name = models.CharField(max_length=2, choices=PENELTY_LENGTH_CHOICES, blank=False, null=False)
length = models.DurationField(blank=False, null=False)
# NOTE: i.e.: "Minor (2:00)", or "Misconduct (10:00")", or "Shot"
# TODO: filter shot
def __str__(self):
return f"{self.name} ({self.length})"
class PeneltyType(models.Model):
PENELTY_TYPE_CHOICES = [
("B", "Boarding"),
("C", "Charging"),
("D", "Delay of Game"),
("X", "Cross-Checking"),
("E", "Elbowing"),
("G", "Grasping the Facemask"),
("H", "High Sticking"),
("O", "Holding"),
("K", "Hooking"),
("I", "Interference"),
("M", "Miscounduct"), # see above where misconduct equals 10 minutes
("R", "Roughing"),
("S", "Slashing"),
("P", "Spearing"),
("T", "Tripping"),
("U", "Unsportsmanlike Conduct"),
]
name = models.CharField(max_length=1, choices=PENELTY_TYPE_CHOICES, blank=False, null=False)
class Penelty(models.Model):
PENELTY_GIVEN_CHOICES = [
("I", "Individual"),
("T", "Team"), # e.g., too many men
]
# default="I" because individual penelties are much more common
penelty_classification = models.CharField(max_length=1, choices=PENELTY_GIVEN_CHOICES, blank=False, null=False, default="I")
penelty_type = models.ForeignKey(PeneltyType, related_name="given_out", on_delete=models.PROTECT, blank=False, null=False)
penelty_length = models.ForeignKey(PeneltyLength, related_name="given_out", on_delete=models.PROTECT, blank=False, null=False)
game = models.ForeignKey(Game, related_name="penelties", on_delete=models.PROTECT, blank=False, null=False)
# NOTE: may be none if team penelty like too many men
on_ind = models.ForeignKey(TeamPlayer, related_name="penelties_given", on_delete=models.PROTECT, blank=True, null=True)
# NOTE: may be noen if individual penelty
on_team = models.ForeignKey(Team, related_name="penelties_given", on_delete=models.PROTECT, blank=True, null=True)
# NOTE: some player will ALWAYS serve the penelty
served_by = models.ForeignKey(TeamPlayer, related_name="penelties_served", on_delete=models.PROTECT, blank=False, null=False)
# NOTE: an indiviaul will not be named in the case of a delay of game; some misconducts, like swearing at a referee also would not list a "drawn_by"
drawn_by = models.ForeignKey(TeamPlayer, related_name="penelties_drawn", on_delete=models.PROTECT, blank=True, null=True)
period = models.IntegerField(choices=PERIOD_CHOICES, blank=False, null=False)
time = models.DurationField(blank=False, null=False)