mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-27 02:47:04 -05:00
97 lines
3.9 KiB
Python
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
|