mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 12:51:09 -05:00
Prevents 500 errors by filtering out parks and rides with null or empty slugs from trending lists and excludes them from database queries where slugs are required. Additionally, it adds conditional rendering in templates to handle parks without slugs gracefully. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0 Replit-Commit-Checkpoint-Type: intermediate_checkpoint
179 lines
6.6 KiB
Python
179 lines
6.6 KiB
Python
from django.shortcuts import render
|
|
from django.views.generic import TemplateView
|
|
from django.db.models import Q
|
|
from django.core.cache import cache
|
|
from apps.parks.models import Park, Company
|
|
from apps.rides.models import Ride
|
|
from apps.core.analytics import PageView
|
|
from django.conf import settings
|
|
import os
|
|
import secrets
|
|
|
|
|
|
def handler404(request, exception):
|
|
return render(request, "404.html", status=404)
|
|
|
|
|
|
def handler500(request):
|
|
return render(request, "500.html", status=500)
|
|
|
|
|
|
class HomeView(TemplateView):
|
|
template_name = "home.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
# Get stats
|
|
context["stats"] = {
|
|
"total_parks": Park.objects.count(),
|
|
"ride_count": Ride.objects.count(),
|
|
"coaster_count": Ride.objects.filter(category="RC").count(),
|
|
}
|
|
|
|
# Try to get trending items from cache first
|
|
trending_parks = cache.get("trending_parks")
|
|
trending_rides = cache.get("trending_rides")
|
|
|
|
# If not in cache, get them directly and cache them
|
|
if trending_parks is None:
|
|
try:
|
|
trending_parks = list(
|
|
PageView.get_trending_items(Park, hours=24, limit=10)
|
|
)
|
|
# Filter out any parks with invalid slugs
|
|
trending_parks = [p for p in trending_parks if getattr(p, 'slug', None)]
|
|
if trending_parks:
|
|
cache.set(
|
|
"trending_parks", trending_parks, 3600
|
|
) # Cache for 1 hour
|
|
else:
|
|
# Fallback to highest rated parks if no trending data
|
|
trending_parks = Park.objects.exclude(
|
|
average_rating__isnull=True
|
|
).exclude(slug__isnull=True).exclude(slug__exact='').order_by("-average_rating")[:10]
|
|
except Exception:
|
|
# Fallback to highest rated parks if trending calculation fails
|
|
trending_parks = Park.objects.exclude(
|
|
average_rating__isnull=True
|
|
).exclude(slug__isnull=True).exclude(slug__exact='').order_by("-average_rating")[:10]
|
|
|
|
if trending_rides is None:
|
|
try:
|
|
trending_rides = list(
|
|
PageView.get_trending_items(Ride, hours=24, limit=10)
|
|
)
|
|
# Filter out any rides with invalid slugs
|
|
trending_rides = [r for r in trending_rides if getattr(r, 'slug', None)]
|
|
if trending_rides:
|
|
cache.set(
|
|
"trending_rides", trending_rides, 3600
|
|
) # Cache for 1 hour
|
|
else:
|
|
# Fallback to highest rated rides if no trending data
|
|
trending_rides = Ride.objects.exclude(
|
|
average_rating__isnull=True
|
|
).exclude(slug__isnull=True).exclude(slug__exact='').order_by("-average_rating")[:10]
|
|
except Exception:
|
|
# Fallback to highest rated rides if trending calculation fails
|
|
trending_rides = Ride.objects.exclude(
|
|
average_rating__isnull=True
|
|
).exclude(slug__isnull=True).exclude(slug__exact='').order_by("-average_rating")[:10]
|
|
|
|
# Get highest rated items (mix of parks and rides)
|
|
highest_rated_parks = list(
|
|
Park.objects.exclude(average_rating__isnull=True)
|
|
.exclude(slug__isnull=True).exclude(slug__exact='')
|
|
.order_by("-average_rating")[:20]
|
|
) # Get more items to randomly select from
|
|
|
|
highest_rated_rides = list(
|
|
Ride.objects.exclude(average_rating__isnull=True)
|
|
.exclude(slug__isnull=True).exclude(slug__exact='')
|
|
.order_by("-average_rating")[:20]
|
|
) # Get more items to randomly select from
|
|
|
|
# Combine and shuffle highest rated items
|
|
all_highest_rated = highest_rated_parks + highest_rated_rides
|
|
secrets.SystemRandom().shuffle(all_highest_rated)
|
|
|
|
# Keep the same context variable names for template compatibility
|
|
context["popular_parks"] = trending_parks
|
|
context["popular_rides"] = trending_rides
|
|
context["highest_rated"] = all_highest_rated[
|
|
:10
|
|
] # Take first 10 after shuffling
|
|
|
|
return context
|
|
|
|
|
|
class SearchView(TemplateView):
|
|
template_name = "search_results.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
if query := self.request.GET.get("q", "").strip():
|
|
# Search parks
|
|
context["parks"] = (
|
|
Park.objects.filter(
|
|
Q(name__icontains=query)
|
|
| Q(location__icontains=query)
|
|
| Q(description__icontains=query)
|
|
)
|
|
.select_related("operating_company")
|
|
.prefetch_related("photos")[:10]
|
|
)
|
|
|
|
# Search rides
|
|
context["rides"] = (
|
|
Ride.objects.filter(
|
|
Q(name__icontains=query)
|
|
| Q(description__icontains=query)
|
|
| Q(manufacturer__name__icontains=query)
|
|
)
|
|
.select_related("park", "coaster_stats")
|
|
.prefetch_related("photos")[:10]
|
|
)
|
|
|
|
# Search companies
|
|
context["companies"] = Company.objects.filter(
|
|
Q(name__icontains=query) | Q(description__icontains=query)
|
|
).prefetch_related("operated_parks", "owned_parks")[:10]
|
|
|
|
return context
|
|
|
|
|
|
def environment_and_settings_view(request):
|
|
# Get all environment variables
|
|
env_vars = dict(os.environ)
|
|
|
|
# Get all Django settings as a dictionary
|
|
settings_vars = {
|
|
setting: getattr(settings, setting)
|
|
for setting in dir(settings)
|
|
if setting.isupper()
|
|
}
|
|
|
|
return render(
|
|
request,
|
|
"environment_and_settings.html",
|
|
{"env_vars": env_vars, "settings_vars": settings_vars},
|
|
)
|
|
|
|
|
|
def test_button_comparison(request):
|
|
"""
|
|
Test view to compare cotton button component with original include version.
|
|
Renders a comprehensive test page with all button variants and combinations.
|
|
"""
|
|
return render(request, "test_button_comparison.html")
|
|
|
|
|
|
def test_auth_modal_comparison(request):
|
|
"""
|
|
Test view to compare cotton auth modal component with original include version.
|
|
Renders a comprehensive test page to verify Alpine.js functionality, styling, and behavior parity.
|
|
"""
|
|
return render(request, "test_auth_modal_comparison.html")
|