Files
thrillwiki_django_no_react/backend/apps/api/v1/serializers/reviews.py
pacnpal ac745cc541 ok
2025-08-28 23:20:09 -04:00

99 lines
3.7 KiB
Python

"""
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 + "..."