""" Views for review-related API endpoints. """ from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import AllowAny from rest_framework import status from django.db.models import Q from drf_spectacular.utils import extend_schema, OpenApiParameter from drf_spectacular.types import OpenApiTypes from itertools import chain from operator import attrgetter from apps.parks.models.reviews import ParkReview from apps.rides.models.reviews import RideReview from ..serializers.reviews import LatestReviewSerializer class LatestReviewsAPIView(APIView): """ API endpoint to get the latest reviews from both parks and rides. Returns a combined list of the most recent reviews across the platform, including username, user avatar, date, score, and review snippet. """ permission_classes = [AllowAny] @extend_schema( summary="Get Latest Reviews", description=( "Retrieve the latest reviews from both parks and rides. " "Returns a combined list sorted by creation date, including " "user information, ratings, and content snippets." ), parameters=[ OpenApiParameter( name="limit", type=OpenApiTypes.INT, location=OpenApiParameter.QUERY, description="Number of reviews to return (default: 20, max: 100)", default=20, ), ], responses={ 200: LatestReviewSerializer(many=True), }, tags=["Reviews"], ) def get(self, request): """Get the latest reviews from both parks and rides.""" # Get limit parameter with validation try: limit = int(request.query_params.get('limit', 20)) limit = min(max(limit, 1), 100) # Clamp between 1 and 100 except (ValueError, TypeError): limit = 20 # Get published reviews from both models park_reviews = ParkReview.objects.filter( is_published=True ).select_related( 'user', 'user__profile', 'park' ).order_by('-created_at')[:limit] ride_reviews = RideReview.objects.filter( is_published=True ).select_related( 'user', 'user__profile', 'ride', 'ride__park' ).order_by('-created_at')[:limit] # Combine and sort by created_at all_reviews = sorted( chain(park_reviews, ride_reviews), key=attrgetter('created_at'), reverse=True )[:limit] # Serialize the combined results serializer = LatestReviewSerializer(all_reviews, many=True) return Response({ 'count': len(all_reviews), 'results': serializer.data }, status=status.HTTP_200_OK)