feat: Implement ride management views and utility functions

- Added functions for checking user privileges, handling photo uploads, preparing form data, and managing form errors.
- Created views for listing, creating, updating, and displaying rides, including category-specific views.
- Integrated submission handling for ride changes and improved user feedback through messages.
- Enhanced data handling with appropriate context and queryset management for better performance and usability.
This commit is contained in:
pacnpal
2024-11-04 05:25:53 +00:00
parent 209e6add1c
commit 5dff4169ae
29 changed files with 1087 additions and 925 deletions

View File

@@ -1,9 +1,11 @@
from typing import Tuple, Optional, Any
from django.db import models
from django.contrib.contenttypes.fields import GenericRelation
from django.utils.text import slugify
from simple_history.models import HistoricalRecords
from history_tracking.models import HistoricalModel
class Ride(models.Model):
class Ride(HistoricalModel):
CATEGORY_CHOICES = [
('RC', 'Roller Coaster'),
('DR', 'Dark Ride'),
@@ -80,31 +82,43 @@ class Ride(models.Model):
updated_at = models.DateTimeField(auto_now=True)
photos = GenericRelation('media.Photo')
reviews = GenericRelation('reviews.Review')
history = HistoricalRecords()
history: HistoricalRecords = HistoricalRecords() # type: ignore
class Meta:
ordering = ['name']
unique_together = ['park', 'slug']
def __str__(self):
def __str__(self) -> str:
return f"{self.name} at {self.park.name}"
def save(self, *args, **kwargs):
def save(self, *args: Any, **kwargs: Any) -> None:
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
@classmethod
def get_by_slug(cls, slug):
"""Get ride by current or historical slug"""
def get_by_slug(cls, slug: str) -> Tuple['Ride', bool]:
"""Get ride by current or historical slug.
Args:
slug: The slug to look up
Returns:
A tuple of (Ride object, bool indicating if it's a historical slug)
Raises:
cls.DoesNotExist: If no ride is found with the given slug
"""
try:
return cls.objects.get(slug=slug), False
except cls.DoesNotExist:
except cls.DoesNotExist as e:
# Check historical slugs
history = cls.history.filter(slug=slug).order_by('-history_date').first()
if history:
return cls.objects.get(id=history.id), True
raise cls.DoesNotExist("No ride found with this slug")
if history := cls.history.filter(slug=slug).order_by('-history_date').first(): # type: ignore[attr-defined]
try:
return cls.objects.get(pk=history.instance.pk), True
except cls.DoesNotExist as inner_e:
raise cls.DoesNotExist("No ride found with this slug") from inner_e
raise cls.DoesNotExist("No ride found with this slug") from e
class RollerCoasterStats(models.Model):
LAUNCH_CHOICES = [
@@ -198,11 +212,11 @@ class RollerCoasterStats(models.Model):
trains_count = models.PositiveIntegerField(null=True, blank=True)
cars_per_train = models.PositiveIntegerField(null=True, blank=True)
seats_per_car = models.PositiveIntegerField(null=True, blank=True)
history = HistoricalRecords()
history: HistoricalRecords = HistoricalRecords() # type: ignore
class Meta:
verbose_name = 'Roller Coaster Statistics'
verbose_name_plural = 'Roller Coaster Statistics'
def __str__(self):
def __str__(self) -> str:
return f"Stats for {self.ride.name}"