Files
thrillwiki_django_no_react/backend/apps/api/v1/serializers/media.py

125 lines
3.9 KiB
Python

"""
Media domain serializers for ThrillWiki API v1.
This module contains serializers for photo uploads, media management,
and related media functionality.
"""
from rest_framework import serializers
from drf_spectacular.utils import (
extend_schema_serializer,
extend_schema_field,
OpenApiExample,
)
# === MEDIA SERIALIZERS ===
class PhotoUploadInputSerializer(serializers.Serializer):
"""Input serializer for photo uploads."""
file = serializers.ImageField()
caption = serializers.CharField(
max_length=500,
required=False,
allow_blank=True,
help_text="Optional caption for the photo",
)
alt_text = serializers.CharField(
max_length=255,
required=False,
allow_blank=True,
help_text="Alt text for accessibility",
)
is_primary = serializers.BooleanField(
default=False, help_text="Whether this should be the primary photo"
)
@extend_schema_serializer(
examples=[
OpenApiExample(
"Photo Detail Example",
summary="Example photo detail response",
description="A photo with full details",
value={
"id": 1,
"url": "https://example.com/media/photos/ride123.jpg",
"thumbnail_url": "https://example.com/media/thumbnails/ride123_thumb.jpg",
"caption": "Amazing view of Steel Vengeance",
"alt_text": "Steel Vengeance roller coaster with blue sky",
"is_primary": True,
"uploaded_at": "2024-08-15T10:30:00Z",
"uploaded_by": {
"id": 1,
"username": "coaster_photographer",
"display_name": "Coaster Photographer",
},
"content_type": "Ride",
"object_id": 123,
},
)
]
)
class PhotoDetailOutputSerializer(serializers.Serializer):
"""Output serializer for photo details."""
id = serializers.IntegerField()
url = serializers.URLField()
thumbnail_url = serializers.URLField(required=False)
caption = serializers.CharField()
alt_text = serializers.CharField()
is_primary = serializers.BooleanField()
uploaded_at = serializers.DateTimeField()
content_type = serializers.CharField()
object_id = serializers.IntegerField()
# File metadata
file_size = serializers.IntegerField()
width = serializers.IntegerField()
height = serializers.IntegerField()
format = serializers.CharField()
# Uploader info
uploaded_by = serializers.SerializerMethodField()
@extend_schema_field(serializers.DictField())
def get_uploaded_by(self, obj) -> dict:
"""Get uploader information."""
return {
"id": obj.uploaded_by.id,
"username": obj.uploaded_by.username,
"display_name": getattr(
obj.uploaded_by, "get_display_name", lambda: obj.uploaded_by.username
)(),
}
class PhotoListOutputSerializer(serializers.Serializer):
"""Output serializer for photo list view."""
id = serializers.IntegerField()
url = serializers.URLField()
thumbnail_url = serializers.URLField(required=False)
caption = serializers.CharField()
is_primary = serializers.BooleanField()
uploaded_at = serializers.DateTimeField()
uploaded_by = serializers.SerializerMethodField()
@extend_schema_field(serializers.DictField())
def get_uploaded_by(self, obj) -> dict:
"""Get uploader information."""
return {
"id": obj.uploaded_by.id,
"username": obj.uploaded_by.username,
}
class PhotoUpdateInputSerializer(serializers.Serializer):
"""Input serializer for updating photos."""
caption = serializers.CharField(max_length=500, required=False, allow_blank=True)
alt_text = serializers.CharField(max_length=255, required=False, allow_blank=True)
is_primary = serializers.BooleanField(required=False)