Files
thrillwiki_django_no_react/backend/apps/api/v1/parks/serializers.py
pacnpal bb7da85516 Refactor API structure and add comprehensive user management features
- Restructure API v1 with improved serializers organization
- Add user deletion requests and moderation queue system
- Implement bulk moderation operations and permissions
- Add user profile enhancements with display names and avatars
- Expand ride and park API endpoints with better filtering
- Add manufacturer API with detailed ride relationships
- Improve authentication flows and error handling
- Update frontend documentation and API specifications
2025-08-29 16:03:51 -04:00

249 lines
7.4 KiB
Python

"""
Park media serializers for ThrillWiki API v1.
This module contains serializers for park-specific media functionality.
Enhanced from rogue implementation to maintain full feature parity.
"""
from rest_framework import serializers
from drf_spectacular.utils import (
extend_schema_field,
extend_schema_serializer,
OpenApiExample,
)
from apps.parks.models import Park, ParkPhoto
@extend_schema_serializer(
examples=[
OpenApiExample(
name="Park Photo with Cloudflare Images",
summary="Complete park photo response",
description="Example response showing all fields including Cloudflare Images URLs and variants",
value={
"id": 456,
"image": "https://imagedelivery.net/account-hash/def456ghi789/public",
"image_url": "https://imagedelivery.net/account-hash/def456ghi789/public",
"image_variants": {
"thumbnail": "https://imagedelivery.net/account-hash/def456ghi789/thumbnail",
"medium": "https://imagedelivery.net/account-hash/def456ghi789/medium",
"large": "https://imagedelivery.net/account-hash/def456ghi789/large",
"public": "https://imagedelivery.net/account-hash/def456ghi789/public",
},
"caption": "Beautiful park entrance",
"alt_text": "Main entrance gate with decorative archway",
"is_primary": True,
"is_approved": True,
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z",
"date_taken": "2023-01-01T11:00:00Z",
"uploaded_by_username": "parkfan456",
"file_size": 1536000,
"dimensions": [1600, 900],
"park_slug": "cedar-point",
"park_name": "Cedar Point",
},
)
]
)
class ParkPhotoOutputSerializer(serializers.ModelSerializer):
"""Enhanced output serializer for park photos with Cloudflare Images support."""
uploaded_by_username = serializers.CharField(
source="uploaded_by.username", read_only=True
)
file_size = serializers.SerializerMethodField()
dimensions = serializers.SerializerMethodField()
image_url = serializers.SerializerMethodField()
image_variants = serializers.SerializerMethodField()
@extend_schema_field(
serializers.IntegerField(allow_null=True, help_text="File size in bytes")
)
def get_file_size(self, obj):
"""Get file size in bytes."""
return obj.file_size
@extend_schema_field(
serializers.ListField(
child=serializers.IntegerField(),
min_length=2,
max_length=2,
allow_null=True,
help_text="Image dimensions as [width, height] in pixels",
)
)
def get_dimensions(self, obj):
"""Get image dimensions as [width, height]."""
return obj.dimensions
@extend_schema_field(
serializers.URLField(
help_text="Full URL to the Cloudflare Images asset", allow_null=True
)
)
def get_image_url(self, obj):
"""Get the full Cloudflare Images URL."""
if obj.image:
return obj.image.url
return None
@extend_schema_field(
serializers.DictField(
child=serializers.URLField(),
help_text="Available Cloudflare Images variants with their URLs",
)
)
def get_image_variants(self, obj):
"""Get available image variants from Cloudflare Images."""
if not obj.image:
return {}
# Common variants for park photos
variants = {
"thumbnail": f"{obj.image.url}/thumbnail",
"medium": f"{obj.image.url}/medium",
"large": f"{obj.image.url}/large",
"public": f"{obj.image.url}/public",
}
return variants
park_slug = serializers.CharField(source="park.slug", read_only=True)
park_name = serializers.CharField(source="park.name", read_only=True)
class Meta:
model = ParkPhoto
fields = [
"id",
"image",
"image_url",
"image_variants",
"caption",
"alt_text",
"is_primary",
"is_approved",
"created_at",
"updated_at",
"date_taken",
"uploaded_by_username",
"file_size",
"dimensions",
"park_slug",
"park_name",
]
read_only_fields = [
"id",
"image_url",
"image_variants",
"created_at",
"updated_at",
"uploaded_by_username",
"file_size",
"dimensions",
"park_slug",
"park_name",
]
class ParkPhotoCreateInputSerializer(serializers.ModelSerializer):
"""Input serializer for creating park photos."""
class Meta:
model = ParkPhoto
fields = [
"image",
"caption",
"alt_text",
"is_primary",
]
class ParkPhotoUpdateInputSerializer(serializers.ModelSerializer):
"""Input serializer for updating park photos."""
class Meta:
model = ParkPhoto
fields = [
"caption",
"alt_text",
"is_primary",
]
class ParkPhotoListOutputSerializer(serializers.ModelSerializer):
"""Optimized output serializer for park photo lists."""
uploaded_by_username = serializers.CharField(
source="uploaded_by.username", read_only=True
)
class Meta:
model = ParkPhoto
fields = [
"id",
"image",
"caption",
"is_primary",
"is_approved",
"created_at",
"uploaded_by_username",
]
read_only_fields = fields
class ParkPhotoApprovalInputSerializer(serializers.Serializer):
"""Input serializer for bulk photo approval operations."""
photo_ids = serializers.ListField(
child=serializers.IntegerField(), help_text="List of photo IDs to approve"
)
approve = serializers.BooleanField(
default=True, help_text="Whether to approve (True) or reject (False) the photos"
)
class ParkPhotoStatsOutputSerializer(serializers.Serializer):
"""Output serializer for park photo statistics."""
total_photos = serializers.IntegerField()
approved_photos = serializers.IntegerField()
pending_photos = serializers.IntegerField()
has_primary = serializers.BooleanField()
recent_uploads = serializers.IntegerField()
# Legacy serializers for backwards compatibility
class ParkPhotoSerializer(serializers.ModelSerializer):
"""Legacy serializer for the ParkPhoto model - maintained for compatibility."""
class Meta:
model = ParkPhoto
fields = (
"id",
"image",
"caption",
"alt_text",
"is_primary",
"uploaded_at",
"uploaded_by",
)
class ParkSerializer(serializers.ModelSerializer):
"""Serializer for the Park model."""
class Meta:
model = Park
fields = (
"id",
"name",
"slug",
"country",
"continent",
"latitude",
"longitude",
"website",
"status",
)