mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 02:31:08 -05:00
86 lines
2.8 KiB
Python
86 lines
2.8 KiB
Python
"""
|
|
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)
|