Files
thrillwiki_django_no_react/backend/apps/api/v1/views/discovery.py

97 lines
3.9 KiB
Python

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