from django.shortcuts import get_object_or_404 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .models import * from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter from rest_framework.generics import ListAPIView from .serializers import PortfolioListViewSerializer, PortfolioCreateSerializer from .paginations import PortfolioPagination from .filters import PortfolioFilter from .services import PortfolioStateChangeService, PortfolioBeforeRelCheckService from django.db import transaction class PortfolioListView(ListAPIView): queryset = Portfolio.objects.filter(is_published=True).order_by('-created_at') serializer_class = PortfolioListViewSerializer pagination_class = PortfolioPagination filterset_class = PortfolioFilter filter_backends = [DjangoFilterBackend, OrderingFilter] ordering_fields = ['view_count', 'like_count', 'scrap_count', 'created_at'] # 허용할 필드 추천순 제외 ordering = ['-created_at'] # 기본 정렬은 최신순 class PortfolioCreateAPIView(APIView): @transaction.atomic def post(self, request): data = request.data.copy() data['owner'] = request.user.id serializer = PortfolioCreateSerializer(data=data) if serializer.is_valid(): serializer.save() return Response({"message": "create portfolio success"}, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class PortfolioDeleteAPIView(APIView): @transaction.atomic def delete(self, request, pk): user = request.user portfolio = get_object_or_404(Portfolio, id=pk) if user != portfolio.owner: return Response({"message": "Not owner"}, status=status.HTTP_403_FORBIDDEN) portfolio.delete() return Response({"message": "delete success"}, status=status.HTTP_200_OK) class PortfolioSetRepresentAPIView(APIView): @transaction.atomic def patch(self, request, pk): user = request.user portfolio = get_object_or_404(Portfolio, id=pk) if user != portfolio.owner: return Response({"message": "Not owner"}, status=status.HTTP_403_FORBIDDEN) is_representing = request.data.get("representing", False) if is_representing: if before_represent := Portfolio.objects.filter(owner=user, is_represent=True).first(): before_represent.is_represent = False before_represent.save() portfolio.is_represent = is_representing portfolio.save() return Response({"is_represented": is_representing}, status=status.HTTP_200_OK) class PortfolioSetPublishAPIView(APIView): @transaction.atomic def patch(self, request, pk): user = request.user portfolio = get_object_or_404(Portfolio, id=pk) if user != portfolio.owner: return Response({"message": "Not owner"}, status=status.HTTP_403_FORBIDDEN) is_publishing = request.data.get("publishing", False) portfolio.is_published = is_publishing portfolio.save() return Response({"is_published": is_publishing}, status=status.HTTP_200_OK) class PortfolioChangeState(APIView): @transaction.atomic def patch(self, request, pk): portfolio = get_object_or_404(Portfolio, pk=pk) user = request.user action_type = request.query_params.get('type') try: if PortfolioBeforeRelCheckService.check_user_portfolio_rel(action_type, portfolio, user): return Response({"message": "already done"}, status=status.HTTP_400_BAD_REQUEST) except ValueError as e: return Response({'message': str(e)}, status=status.HTTP_400_BAD_REQUEST) return self._handle_action(action_type, portfolio, user, add=True) @transaction.atomic def delete(self, request, pk): portfolio = get_object_or_404(Portfolio, pk=pk) user = request.user action_type = request.query_params.get('type') try: if not PortfolioBeforeRelCheckService.check_user_portfolio_rel(action_type, portfolio, user): return Response({"message": "never done before"}, status=status.HTTP_400_BAD_REQUEST) except ValueError as e: return Response({'message': str(e)}, status=status.HTTP_400_BAD_REQUEST) return self._handle_action(action_type, portfolio, user, add=False) def _handle_action(self, action_type, portfolio, user, add=True): if not action_type: return Response({'message': 'Missing action type'}, status=status.HTTP_400_BAD_REQUEST) try: PortfolioStateChangeService.change_user_portfolio_rel(action_type, portfolio, user, add) PortfolioStateChangeService.change_count_portfolio_state(action_type, portfolio, add) except ValueError as e: return Response({'message': str(e)}, status=status.HTTP_400_BAD_REQUEST) return Response({ 'message': f'{action_type} {"added" if add else "removed"}' }, status=status.HTTP_200_OK)