from django.views.generic import DetailView, ListView from django.shortcuts import get_object_or_404 from django.core.serializers.json import DjangoJSONEncoder from django.urls import reverse from django.db.models import Q from .models import Ride, RollerCoasterStats from parks.models import Park from core.views import SlugRedirectMixin class RideDetailView(SlugRedirectMixin, DetailView): model = Ride template_name = 'rides/ride_detail.html' context_object_name = 'ride' slug_url_kwarg = 'ride_slug' def get_object(self, queryset=None): if queryset is None: queryset = self.get_queryset() park_slug = self.kwargs.get('park_slug') ride_slug = self.kwargs.get('ride_slug') # Try to get by current or historical slug obj, is_old_slug = self.model.get_by_slug(ride_slug) if obj.park.slug != park_slug: raise self.model.DoesNotExist("Park slug doesn't match") return obj def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) if self.object.category == 'RC': context['coaster_stats'] = RollerCoasterStats.objects.filter(ride=self.object).first() return context def get_redirect_url_pattern(self): return 'ride_detail' def get_redirect_url_kwargs(self): return { 'park_slug': self.object.park.slug, 'ride_slug': self.object.slug } class RideListView(ListView): model = Ride template_name = 'rides/ride_list.html' context_object_name = 'rides' def get_queryset(self): queryset = Ride.objects.select_related('park', 'coaster_stats', 'manufacturer').prefetch_related('photos') search = self.request.GET.get('search', '').strip() or None category = self.request.GET.get('category', '').strip() or None status = self.request.GET.get('status', '').strip() or None manufacturer = self.request.GET.get('manufacturer', '').strip() or None if search: queryset = queryset.filter( Q(name__icontains=search) | Q(park__name__icontains=search) ) if category: queryset = queryset.filter(category=category) if status: queryset = queryset.filter(status=status) if manufacturer: # Example: Exclude null manufacturers in RideListView queryset = Ride.objects.exclude(manufacturer__isnull=True) return queryset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Exclude cases where manufacturer is null or an empty string context['manufacturers'] = list( Ride.objects.exclude(manufacturer__isnull=True) .exclude(manufacturer__isnull=True) .values_list('manufacturer__name', flat=True) .distinct().order_by('manufacturer__name') ) # Add current filter values to context context['current_filters'] = { 'search': self.request.GET.get('search', ''), 'category': self.request.GET.get('category', ''), 'status': self.request.GET.get('status', ''), 'manufacturer': self.request.GET.get('manufacturer', '') } return context def get(self, request, *args, **kwargs): # Check if this is an HTMX request if request.htmx: # If it is, return just the rides list partial self.template_name = 'rides/partials/ride_list.html' return super().get(request, *args, **kwargs)