feat: Add blog, media, and support apps, implement ride credits and image API, and remove toplist feature.

This commit is contained in:
pacnpal
2025-12-26 15:15:28 -05:00
parent cd8868a591
commit 00699d53b4
77 changed files with 7274 additions and 538 deletions

View File

@@ -0,0 +1,96 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import AllowAny
from django.db.models import F
from django.utils import timezone
from drf_spectacular.utils import extend_schema
from datetime import timedelta
from apps.parks.models import Park
from apps.rides.models import Ride
class DiscoveryAPIView(APIView):
"""
API endpoint for discovery content (Top Lists, Opening/Closing Soon).
"""
permission_classes = [AllowAny]
@extend_schema(
summary="Get discovery content",
description="Retrieve curated lists for discovery tabs (Top, Opening, Closing).",
responses={200: "object"},
tags=["Discovery"],
)
def get(self, request):
today = timezone.now().date()
limit = 10
# --- TOP LISTS ---
# Top Parks by average rating
top_parks = Park.objects.filter(average_rating__isnull=False).order_by("-average_rating")[:limit]
# Top Rides by average rating (fallback to RideRanking in future)
top_rides = Ride.objects.filter(average_rating__isnull=False).order_by("-average_rating")[:limit]
# --- OPENING ---
# Opening Soon (Future opening date)
opening_soon_parks = Park.objects.filter(opening_date__gt=today).order_by("opening_date")[:limit]
opening_soon_rides = Ride.objects.filter(opening_date__gt=today).order_by("opening_date")[:limit]
# Recently Opened (Past opening date, descending)
recently_opened_parks = Park.objects.filter(opening_date__lte=today).order_by("-opening_date")[:limit]
recently_opened_rides = Ride.objects.filter(opening_date__lte=today).order_by("-opening_date")[:limit]
# --- CLOSING ---
# Closing Soon (Future closing date)
closing_soon_parks = Park.objects.filter(closing_date__gt=today).order_by("closing_date")[:limit]
closing_soon_rides = Ride.objects.filter(closing_date__gt=today).order_by("closing_date")[:limit]
# Recently Closed (Past closing date, descending)
recently_closed_parks = Park.objects.filter(closing_date__lte=today).order_by("-closing_date")[:limit]
recently_closed_rides = Ride.objects.filter(closing_date__lte=today).order_by("-closing_date")[:limit]
data = {
"top_parks": self._serialize(top_parks, "park"),
"top_rides": self._serialize(top_rides, "ride"),
"opening_soon": {
"parks": self._serialize(opening_soon_parks, "park"),
"rides": self._serialize(opening_soon_rides, "ride"),
},
"recently_opened": {
"parks": self._serialize(recently_opened_parks, "park"),
"rides": self._serialize(recently_opened_rides, "ride"),
},
"closing_soon": {
"parks": self._serialize(closing_soon_parks, "park"),
"rides": self._serialize(closing_soon_rides, "ride"),
},
"recently_closed": {
"parks": self._serialize(recently_closed_parks, "park"),
"rides": self._serialize(recently_closed_rides, "ride"),
}
}
return Response(data)
def _serialize(self, queryset, type_):
results = []
for item in queryset:
data = {
"id": item.id,
"name": item.name,
"slug": item.slug,
"average_rating": item.average_rating,
}
if type_ == "park":
data.update({
"city": item.location.city if item.location else None,
"state": item.location.state if item.location else None,
})
elif type_ == "ride":
data.update({
"park_name": item.park.name,
"park_slug": item.park.slug
})
results.append(data)
return results