""" Serializers for review-related API endpoints. """ from rest_framework import serializers from apps.parks.models.reviews import ParkReview from apps.rides.models.reviews import RideReview from apps.accounts.models import User class ReviewUserSerializer(serializers.ModelSerializer): """Serializer for user information in reviews.""" avatar_url = serializers.SerializerMethodField() display_name = serializers.SerializerMethodField() class Meta: model = User fields = ["username", "display_name", "avatar_url"] def get_avatar_url(self, obj): """Get the user's avatar URL.""" if hasattr(obj, "profile") and obj.profile: return obj.profile.get_avatar() return "/static/images/default-avatar.png" def get_display_name(self, obj): """Get the user's display name.""" return obj.get_display_name() class LatestReviewSerializer(serializers.Serializer): """Serializer for latest reviews combining park and ride reviews.""" id = serializers.IntegerField() type = serializers.CharField() # 'park' or 'ride' title = serializers.CharField() content_snippet = serializers.CharField() rating = serializers.IntegerField() created_at = serializers.DateTimeField() user = ReviewUserSerializer() # Subject information (park or ride) subject_name = serializers.CharField() subject_slug = serializers.CharField() subject_url = serializers.CharField() # Park information (for ride reviews) park_name = serializers.CharField(allow_null=True) park_slug = serializers.CharField(allow_null=True) park_url = serializers.CharField(allow_null=True) def to_representation(self, instance): """Convert review instance to serialized representation.""" if isinstance(instance, ParkReview): return { "id": instance.pk, "type": "park", "title": instance.title, "content_snippet": self._get_content_snippet(instance.content), "rating": instance.rating, "created_at": instance.created_at, "user": ReviewUserSerializer(instance.user).data, "subject_name": instance.park.name, "subject_slug": instance.park.slug, "subject_url": f"/parks/{instance.park.slug}/", "park_name": None, "park_slug": None, "park_url": None, } elif isinstance(instance, RideReview): return { "id": instance.pk, "type": "ride", "title": instance.title, "content_snippet": self._get_content_snippet(instance.content), "rating": instance.rating, "created_at": instance.created_at, "user": ReviewUserSerializer(instance.user).data, "subject_name": instance.ride.name, "subject_slug": instance.ride.slug, "subject_url": f"/parks/{instance.ride.park.slug}/rides/{instance.ride.slug}/", "park_name": instance.ride.park.name, "park_slug": instance.ride.park.slug, "park_url": f"/parks/{instance.ride.park.slug}/", } return {} def _get_content_snippet(self, content, max_length=150): """Get a snippet of the review content.""" if len(content) <= max_length: return content # Find the last complete word within the limit snippet = content[:max_length] last_space = snippet.rfind(" ") if last_space > 0: snippet = snippet[:last_space] return snippet + "..."