from django.db import models from simple_history.models import HistoricalRecords class TeamAlias(models.Model): """ Historical team name aliases for resolution. Handles team renames, relocations, and alternate names. """ ALIAS_TYPE_CHOICES = [ ('full_name', 'Full Name'), ('city_name', 'City + Name'), ('abbreviation', 'Abbreviation'), ('nickname', 'Nickname'), ('historical', 'Historical Name'), ] team = models.ForeignKey( 'core.Team', on_delete=models.CASCADE, related_name='aliases' ) alias = models.CharField( max_length=200, help_text='The alias text to match against' ) alias_type = models.CharField( max_length=20, choices=ALIAS_TYPE_CHOICES, default='full_name' ) valid_from = models.DateField( null=True, blank=True, help_text='Date from which this alias is valid (inclusive)' ) valid_until = models.DateField( null=True, blank=True, help_text='Date until which this alias is valid (inclusive)' ) is_primary = models.BooleanField( default=False, help_text='Whether this is a primary/preferred alias' ) source = models.CharField( max_length=200, blank=True, help_text='Source of this alias (e.g., ESPN, Basketball-Reference)' ) notes = models.TextField( blank=True, help_text='Notes about this alias (e.g., relocation details)' ) # Metadata created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) # Audit trail history = HistoricalRecords() class Meta: ordering = ['team', '-valid_from'] verbose_name = 'Team Alias' verbose_name_plural = 'Team Aliases' indexes = [ models.Index(fields=['alias']), models.Index(fields=['team', 'valid_from', 'valid_until']), ] def __str__(self): date_range = "" if self.valid_from or self.valid_until: start = self.valid_from.strftime('%Y') if self.valid_from else '...' end = self.valid_until.strftime('%Y') if self.valid_until else 'present' date_range = f" ({start}-{end})" return f"{self.alias} → {self.team.abbreviation}{date_range}" def is_valid_for_date(self, check_date): """Check if this alias is valid for a given date.""" if self.valid_from and check_date < self.valid_from: return False if self.valid_until and check_date > self.valid_until: return False return True class StadiumAlias(models.Model): """ Historical stadium name aliases for resolution. Handles naming rights changes and alternate names. """ ALIAS_TYPE_CHOICES = [ ('official', 'Official Name'), ('former', 'Former Name'), ('nickname', 'Nickname'), ('abbreviation', 'Abbreviation'), ] stadium = models.ForeignKey( 'core.Stadium', on_delete=models.CASCADE, related_name='aliases' ) alias = models.CharField( max_length=200, help_text='The alias text to match against' ) alias_type = models.CharField( max_length=20, choices=ALIAS_TYPE_CHOICES, default='official' ) valid_from = models.DateField( null=True, blank=True, help_text='Date from which this alias is valid (inclusive)' ) valid_until = models.DateField( null=True, blank=True, help_text='Date until which this alias is valid (inclusive)' ) is_primary = models.BooleanField( default=False, help_text='Whether this is the current/primary name' ) source = models.CharField( max_length=200, blank=True, help_text='Source of this alias' ) notes = models.TextField( blank=True, help_text='Notes about this alias (e.g., naming rights deal)' ) # Metadata created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) # Audit trail history = HistoricalRecords() class Meta: ordering = ['stadium', '-valid_from'] verbose_name = 'Stadium Alias' verbose_name_plural = 'Stadium Aliases' indexes = [ models.Index(fields=['alias']), models.Index(fields=['stadium', 'valid_from', 'valid_until']), ] def __str__(self): date_range = "" if self.valid_from or self.valid_until: start = self.valid_from.strftime('%Y') if self.valid_from else '...' end = self.valid_until.strftime('%Y') if self.valid_until else 'present' date_range = f" ({start}-{end})" return f"{self.alias} → {self.stadium.name}{date_range}" def is_valid_for_date(self, check_date): """Check if this alias is valid for a given date.""" if self.valid_from and check_date < self.valid_from: return False if self.valid_until and check_date > self.valid_until: return False return True