mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 02:31:08 -05:00
223 lines
6.9 KiB
Python
223 lines
6.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 UPLOAD SERIALIZERS ===
|
|
|
|
|
|
@extend_schema_serializer(
|
|
examples=[
|
|
OpenApiExample(
|
|
"Photo Upload Example",
|
|
summary="Example photo upload request",
|
|
description="Upload a photo for a park or ride",
|
|
value={
|
|
"photo": "file_upload",
|
|
"app_label": "parks",
|
|
"model": "park",
|
|
"object_id": 123,
|
|
"caption": "Beautiful view of the park entrance",
|
|
"alt_text": "Park entrance with landscaping",
|
|
"is_primary": True,
|
|
"photo_type": "general",
|
|
},
|
|
)
|
|
]
|
|
)
|
|
class PhotoUploadInputSerializer(serializers.Serializer):
|
|
"""Input serializer for photo uploads."""
|
|
|
|
photo = serializers.ImageField(
|
|
help_text="The image file to upload"
|
|
)
|
|
app_label = serializers.CharField(
|
|
max_length=100,
|
|
help_text="App label of the content object (e.g., 'parks', 'rides')"
|
|
)
|
|
model = serializers.CharField(
|
|
max_length=100,
|
|
help_text="Model name of the content object (e.g., 'park', 'ride')"
|
|
)
|
|
object_id = serializers.IntegerField(
|
|
help_text="ID of the content object"
|
|
)
|
|
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="Optional alt text for accessibility"
|
|
)
|
|
is_primary = serializers.BooleanField(
|
|
default=False,
|
|
help_text="Whether this should be the primary photo"
|
|
)
|
|
photo_type = serializers.CharField(
|
|
max_length=50,
|
|
default="general",
|
|
required=False,
|
|
help_text="Type of photo (for rides: 'general', 'on_ride', 'construction', etc.)"
|
|
)
|
|
|
|
|
|
class PhotoUploadOutputSerializer(serializers.Serializer):
|
|
"""Output serializer for photo uploads."""
|
|
id = serializers.IntegerField()
|
|
url = serializers.CharField()
|
|
caption = serializers.CharField()
|
|
alt_text = serializers.CharField()
|
|
is_primary = serializers.BooleanField()
|
|
message = serializers.CharField()
|
|
|
|
|
|
# === PHOTO DETAIL SERIALIZERS ===
|
|
|
|
|
|
@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,
|
|
"file_size": 2048576,
|
|
"width": 1920,
|
|
"height": 1080,
|
|
"format": "JPEG",
|
|
},
|
|
)
|
|
]
|
|
)
|
|
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)
|
|
|
|
|
|
# === MEDIA STATS SERIALIZERS ===
|
|
|
|
|
|
class MediaStatsOutputSerializer(serializers.Serializer):
|
|
"""Output serializer for media statistics."""
|
|
|
|
total_photos = serializers.IntegerField()
|
|
photos_by_content_type = serializers.DictField()
|
|
recent_uploads = serializers.IntegerField()
|
|
top_uploaders = serializers.ListField()
|
|
storage_usage = serializers.DictField()
|
|
|
|
|
|
# === BULK OPERATIONS SERIALIZERS ===
|
|
|
|
|
|
class BulkPhotoActionInputSerializer(serializers.Serializer):
|
|
"""Input serializer for bulk photo actions."""
|
|
|
|
photo_ids = serializers.ListField(
|
|
child=serializers.IntegerField(),
|
|
help_text="List of photo IDs to perform action on"
|
|
)
|
|
action = serializers.ChoiceField(
|
|
choices=[
|
|
('delete', 'Delete'),
|
|
('approve', 'Approve'),
|
|
('reject', 'Reject'),
|
|
],
|
|
help_text="Action to perform on selected photos"
|
|
)
|
|
|
|
|
|
class BulkPhotoActionOutputSerializer(serializers.Serializer):
|
|
"""Output serializer for bulk photo actions."""
|
|
|
|
success_count = serializers.IntegerField()
|
|
failed_count = serializers.IntegerField()
|
|
errors = serializers.ListField(child=serializers.CharField(), required=False)
|
|
message = serializers.CharField()
|