from django.db import models from django.utils.text import slugify from django.urls import reverse from typing import Tuple, Optional, ClassVar, TYPE_CHECKING import pghistory from history_tracking.models import TrackedModel, HistoricalSlug @pghistory.track() class Operator(TrackedModel): """ Companies that operate theme parks (replaces Company.owner) """ name = models.CharField(max_length=255) slug = models.SlugField(max_length=255, unique=True) description = models.TextField(blank=True) website = models.URLField(blank=True) founded_year = models.PositiveIntegerField(blank=True, null=True) headquarters = models.CharField(max_length=255, blank=True) parks_count = models.IntegerField(default=0) rides_count = models.IntegerField(default=0) objects: ClassVar[models.Manager['Operator']] class Meta: ordering = ['name'] verbose_name = 'Operator' verbose_name_plural = 'Operators' def __str__(self) -> str: return self.name def save(self, *args, **kwargs) -> None: if not self.slug: self.slug = slugify(self.name) super().save(*args, **kwargs) def get_absolute_url(self) -> str: return reverse('operators:detail', kwargs={'slug': self.slug}) @classmethod def get_by_slug(cls, slug: str) -> Tuple['Operator', bool]: """Get operator by slug, checking historical slugs if needed""" try: return cls.objects.get(slug=slug), False except cls.DoesNotExist: # Check pghistory first history_model = cls.get_history_model() history_entry = ( history_model.objects.filter(slug=slug) .order_by('-pgh_created_at') .first() ) if history_entry: return cls.objects.get(id=history_entry.pgh_obj_id), True # Check manual slug history as fallback try: historical = HistoricalSlug.objects.get( content_type__model='operator', slug=slug ) return cls.objects.get(pk=historical.object_id), True except (HistoricalSlug.DoesNotExist, cls.DoesNotExist): raise cls.DoesNotExist()