mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 02:11:08 -05:00
117 lines
4.0 KiB
Python
117 lines
4.0 KiB
Python
"""
|
|
Park API views for ThrillWiki API v1.
|
|
"""
|
|
import logging
|
|
|
|
from django.core.exceptions import PermissionDenied
|
|
from drf_spectacular.utils import extend_schema_view, extend_schema
|
|
from drf_spectacular.types import OpenApiTypes
|
|
from rest_framework import status
|
|
from rest_framework.decorators import action
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from rest_framework.viewsets import ModelViewSet
|
|
|
|
from apps.parks.models import ParkPhoto
|
|
from apps.parks.services import ParkMediaService
|
|
from ..media.serializers import (
|
|
PhotoUpdateInputSerializer,
|
|
PhotoListOutputSerializer,
|
|
)
|
|
from .serializers import ParkPhotoSerializer
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@extend_schema_view(
|
|
list=extend_schema(
|
|
summary="List park photos",
|
|
description="Retrieve a list of photos for a specific park.",
|
|
responses={200: PhotoListOutputSerializer(many=True)},
|
|
tags=["Parks"],
|
|
),
|
|
retrieve=extend_schema(
|
|
summary="Get park photo details",
|
|
description="Retrieve detailed information about a specific park photo.",
|
|
responses={
|
|
200: ParkPhotoSerializer,
|
|
404: OpenApiTypes.OBJECT,
|
|
},
|
|
tags=["Parks"],
|
|
),
|
|
update=extend_schema(
|
|
summary="Update park photo",
|
|
description="Update park photo information (caption, alt text, etc.)",
|
|
request=PhotoUpdateInputSerializer,
|
|
responses={
|
|
200: ParkPhotoSerializer,
|
|
400: OpenApiTypes.OBJECT,
|
|
403: OpenApiTypes.OBJECT,
|
|
404: OpenApiTypes.OBJECT,
|
|
},
|
|
tags=["Parks"],
|
|
),
|
|
destroy=extend_schema(
|
|
summary="Delete park photo",
|
|
description="Delete a park photo (only by owner or admin)",
|
|
responses={
|
|
204: None,
|
|
403: OpenApiTypes.OBJECT,
|
|
404: OpenApiTypes.OBJECT,
|
|
},
|
|
tags=["Parks"],
|
|
),
|
|
)
|
|
class ParkPhotoViewSet(ModelViewSet):
|
|
"""ViewSet for managing park photos."""
|
|
|
|
queryset = ParkPhoto.objects.select_related("park", "uploaded_by").all()
|
|
permission_classes = [IsAuthenticated]
|
|
lookup_field = "id"
|
|
|
|
def get_serializer_class(self):
|
|
"""Return appropriate serializer based on action."""
|
|
if self.action == "list":
|
|
return PhotoListOutputSerializer
|
|
elif self.action in ["update", "partial_update"]:
|
|
return PhotoUpdateInputSerializer
|
|
return ParkPhotoSerializer
|
|
|
|
def perform_update(self, serializer):
|
|
"""Update photo with permission check."""
|
|
photo = self.get_object()
|
|
if not (
|
|
self.request.user == photo.uploaded_by
|
|
or self.request.user.has_perm("parks.change_parkphoto")
|
|
):
|
|
raise PermissionDenied("You do not have permission to edit this photo.")
|
|
serializer.save()
|
|
|
|
def perform_destroy(self, instance):
|
|
"""Delete photo with permission check."""
|
|
if not (
|
|
self.request.user == instance.uploaded_by
|
|
or self.request.user.has_perm("parks.delete_parkphoto")
|
|
):
|
|
raise PermissionDenied("You do not have permission to delete this photo.")
|
|
instance.delete()
|
|
|
|
@action(detail=True, methods=["post"])
|
|
def set_primary(self, request, id=None):
|
|
"""Set this photo as the primary photo for its park."""
|
|
photo = self.get_object()
|
|
if not (
|
|
request.user == photo.uploaded_by
|
|
or request.user.has_perm("parks.change_parkphoto")
|
|
):
|
|
return Response(
|
|
{"error": "You do not have permission to edit photos for this park."},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
try:
|
|
ParkMediaService.set_primary_photo(photo.park, photo)
|
|
return Response({"message": "Photo set as primary successfully."})
|
|
except Exception as e:
|
|
logger.error(f"Error in set_primary_photo: {str(e)}", exc_info=True)
|
|
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
|