mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 06:11:07 -05:00
Improve site performance and adhere to best practices
Optimize database queries for parks and rides using select_related and prefetch_related, implement caching for homepage stats and trending items, and update the ride detail template to remove unnecessary link wrapping. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 48ecdb60-d0f0-4b75-95c9-34e409ef35fb Replit-Commit-Checkpoint-Type: intermediate_checkpoint
This commit is contained in:
@@ -6,8 +6,28 @@ from apps.parks.models import Park, Company
|
||||
from apps.rides.models import Ride
|
||||
from apps.core.analytics import PageView
|
||||
from django.conf import settings
|
||||
from django.db import connection
|
||||
import os
|
||||
import secrets
|
||||
import logging
|
||||
|
||||
# Set up logger for query debugging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def optimize_park_queryset(queryset):
|
||||
"""Add proper select_related and prefetch_related to park querysets"""
|
||||
return queryset.select_related(
|
||||
'operator', 'property_owner', 'card_image', 'banner_image'
|
||||
).prefetch_related('photos')
|
||||
|
||||
|
||||
def optimize_ride_queryset(queryset):
|
||||
"""Add proper select_related and prefetch_related to ride querysets"""
|
||||
return queryset.select_related(
|
||||
'park', 'park__operator', 'manufacturer', 'designer', 'card_image',
|
||||
'ride_model', 'park_area'
|
||||
).prefetch_related('photos')
|
||||
|
||||
|
||||
def handler404(request, exception):
|
||||
@@ -22,14 +42,22 @@ class HomeView(TemplateView):
|
||||
template_name = "home.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
# Track query count for performance monitoring
|
||||
queries_start = len(connection.queries)
|
||||
|
||||
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(),
|
||||
}
|
||||
# Get stats - try cache first
|
||||
stats = cache.get("homepage_stats")
|
||||
if stats is None:
|
||||
stats = {
|
||||
"total_parks": Park.objects.count(),
|
||||
"ride_count": Ride.objects.count(),
|
||||
"coaster_count": Ride.objects.filter(category="RC").count(),
|
||||
}
|
||||
# Cache stats for 30 minutes
|
||||
cache.set("homepage_stats", stats, 1800)
|
||||
context["stats"] = stats
|
||||
|
||||
# Try to get trending items from cache first
|
||||
trending_parks = cache.get("trending_parks")
|
||||
@@ -38,9 +66,11 @@ class HomeView(TemplateView):
|
||||
# If not in cache, get them directly and cache them
|
||||
if trending_parks is None:
|
||||
try:
|
||||
trending_parks = list(
|
||||
# Get trending parks with optimized queries
|
||||
trending_parks_qs = optimize_park_queryset(
|
||||
PageView.get_trending_items(Park, hours=24, limit=10)
|
||||
)
|
||||
trending_parks = list(trending_parks_qs)
|
||||
# Filter out any parks with invalid slugs
|
||||
trending_parks = [p for p in trending_parks if getattr(p, 'slug', None)]
|
||||
if trending_parks:
|
||||
@@ -51,18 +81,24 @@ class HomeView(TemplateView):
|
||||
# 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]
|
||||
).exclude(slug__isnull=True).exclude(slug__exact='').select_related(
|
||||
'operator', 'property_owner', 'card_image', 'banner_image'
|
||||
).prefetch_related('photos').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]
|
||||
).exclude(slug__isnull=True).exclude(slug__exact='').select_related(
|
||||
'operator', 'property_owner', 'card_image', 'banner_image'
|
||||
).prefetch_related('photos').order_by("-average_rating")[:10]
|
||||
|
||||
if trending_rides is None:
|
||||
try:
|
||||
trending_rides = list(
|
||||
# Get trending rides with optimized queries
|
||||
trending_rides_qs = optimize_ride_queryset(
|
||||
PageView.get_trending_items(Ride, hours=24, limit=10)
|
||||
)
|
||||
trending_rides = list(trending_rides_qs)
|
||||
# Filter out any rides with invalid slugs
|
||||
trending_rides = [r for r in trending_rides if getattr(r, 'slug', None)]
|
||||
if trending_rides:
|
||||
@@ -73,23 +109,34 @@ class HomeView(TemplateView):
|
||||
# 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]
|
||||
).exclude(slug__isnull=True).exclude(slug__exact='').select_related(
|
||||
'park', 'park__operator', 'manufacturer', 'designer', 'card_image',
|
||||
'ride_model', 'park_area'
|
||||
).prefetch_related('photos').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]
|
||||
).exclude(slug__isnull=True).exclude(slug__exact='').select_related(
|
||||
'park', 'park__operator', 'manufacturer', 'designer', 'card_image',
|
||||
'ride_model', 'park_area'
|
||||
).prefetch_related('photos').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='')
|
||||
.select_related('operator', 'property_owner', 'card_image', 'banner_image')
|
||||
.prefetch_related('photos')
|
||||
.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='')
|
||||
.select_related('park', 'park__operator', 'manufacturer', 'designer', 'card_image',
|
||||
'ride_model', 'park_area')
|
||||
.prefetch_related('photos')
|
||||
.order_by("-average_rating")[:20]
|
||||
) # Get more items to randomly select from
|
||||
|
||||
@@ -104,6 +151,11 @@ class HomeView(TemplateView):
|
||||
:10
|
||||
] # Take first 10 after shuffling
|
||||
|
||||
# Log query count for debugging
|
||||
queries_end = len(connection.queries)
|
||||
query_count = queries_end - queries_start
|
||||
logger.info(f"HomeView executed {query_count} queries")
|
||||
|
||||
return context
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user