Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions apps/aquatics/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
FishtankBackgroundListView,
ApplyFishtankBackgroundView,
FishtankExportView,
FishtankSelectableFishView,
FishtankExportSelectionView,
)
from .views_aquarium import *

Expand All @@ -15,13 +17,17 @@
path("fishtank/backgrounds/", FishtankBackgroundListView.as_view()),
path("fishtank/<int:repo_id>/apply-background/", ApplyFishtankBackgroundView.as_view()),
path("fishtank/<int:repo_id>/export/", FishtankExportView.as_view()),
path("svg/", AquariumSVGView.as_view(), name="aquarium-svg"),
path("fishtank/<int:repo_id>/selectable-fish/", FishtankSelectableFishView.as_view()),
path("fishtank/<int:repo_id>/export-selection/", FishtankExportSelectionView.as_view()),

path("aquarium/", AquariumDetailView.as_view()),
path("aquarium/my-fishes/", MyUnlockedFishListView.as_view()),
path("aquarium/add-fish/", AquariumAddFishView.as_view()),
path("aquarium/remove-fish/<int:fish_id>/", AquariumRemoveFishView.as_view()),
#path("aquarium/add-fish/", AquariumAddFishView.as_view()),
#path("aquarium/remove-fish/<int:fish_id>/", AquariumRemoveFishView.as_view()),
path("aquarium/backgrounds/", AquariumBackgroundListView.as_view()),
path("aquarium/apply-background/", AquariumApplyBackgroundView.as_view()),
path("aquarium/export/", AquariumExportView.as_view()),
path("aquarium/svg/", AquariumSVGView.as_view()),
path("aquarium/selectable-fish/", AquariumSelectableFishView.as_view()),
path("aquarium/export-selection/", AquariumExportSelectionView.as_view()),
]
62 changes: 62 additions & 0 deletions apps/aquatics/views_aquarium.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,65 @@ class AquariumSVGView(APIView):
def get(self, request):
svg = render_aquarium_svg(request.user)
return Response(svg, content_type="image/svg+xml")


# 9) 아쿠아리움 선택 가능한 물고기 목록
class AquariumSelectableFishView(APIView):
permission_classes = [IsAuthenticated]

@swagger_auto_schema(
operation_summary="선택 가능한 물고기 목록 조회",
operation_description="유저가 보유한 모든 ContributionFish를 selectable 형태로 반환합니다.",
responses={200: "Selectable fish list"}
)
def get(self, request):
user = request.user
aquarium = user.aquarium

fishes = ContributionFish.objects.filter(contributor__user=user) \
.select_related("fish_species", "contributor__repository")

data = []
for f in fishes:
data.append({
"id": f.id,
"species": f.fish_species.name,
"repo_name": f.contributor.repository.name,
"selected": (f.aquarium_id == aquarium.id)
})

return Response({"fishes": data}, status=200)
# 10) Export: 프론트 선택 상태를 실제 DB에 반영
class AquariumExportSelectionView(APIView):
permission_classes = [IsAuthenticated]

@swagger_auto_schema(
operation_summary="아쿠아리움 Export - 선택된 물고기 저장",
operation_description="프론트에서 최종 선택된 물고기 ID 목록을 받아 DB에 반영합니다.",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
"fish_ids": openapi.Schema(
type=openapi.TYPE_ARRAY,
items=openapi.Items(type=openapi.TYPE_INTEGER)
)
},
required=["fish_ids"]
),
responses={200: "Saved"}
)
def post(self, request):
user = request.user
aquarium = user.aquarium
selected_ids = request.data.get("fish_ids", [])

# 1) 유저가 소유한 모든 fish 가져오기
all_my_fish = ContributionFish.objects.filter(contributor__user=user)

# 2) 선택되지 않은 물고기 → aquarium에서 제거
all_my_fish.exclude(id__in=selected_ids).update(aquarium=None)

# 3) 선택된 물고기 → aquarium에 추가
all_my_fish.filter(id__in=selected_ids).update(aquarium=aquarium)

return Response({"detail": "Aquarium updated"}, status=200)
71 changes: 69 additions & 2 deletions apps/aquatics/views_fishtank.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#fishtank views.py

from apps.repositories.models import Repository
from apps.aquatics.models import Fishtank, FishtankSetting, OwnBackground
from apps.aquatics.models import Fishtank, FishtankSetting, OwnBackground,ContributionFish
from apps.aquatics.serializers_fishtank import (
FishtankDetailSerializer,
FishtankBackgroundSerializer,
Expand Down Expand Up @@ -151,4 +151,71 @@ class FishtankExportView(APIView):
def post(self, request, repo_id):

# 저장 필드가 모델에 아직 없기 때문에, 저장 로직은 후에 추가 가능
return Response({"detail": "Saved"}, status=200)
return Response({"detail": "Saved"}, status=200)

# 9) 피쉬탱크 선택 가능한 물고기 목록
class FishtankSelectableFishView(APIView):
permission_classes = [IsAuthenticated]

@swagger_auto_schema(
operation_summary="피쉬탱크 선택 가능한 물고기 목록 조회",
operation_description="레포지토리 내 ContributionFish 전체를 조회하고, is_visible 여부를 selected로 반환합니다.",
)
def get(self, request, repo_id):
try:
fishtank = Fishtank.objects.get(repository_id=repo_id)
except Fishtank.DoesNotExist:
return Response({"detail": "Fishtank not found"}, status=404)

fishes = ContributionFish.objects.filter(
contributor__repository_id=repo_id
).select_related("fish_species", "contributor__user")

data = []
for f in fishes:
data.append({
"id": f.id,
"username": f.contributor.user.username,
"species": f.fish_species.name,
"commit_count": f.contributor.commit_count,
"selected": f.is_visible,
})

return Response({"fishes": data}, status=200)
# 10) 피쉬탱크 Export → 선택 상태 실제 저장
class FishtankExportSelectionView(APIView):
permission_classes = [IsAuthenticated]

@swagger_auto_schema(
operation_summary="피쉬탱크 Export - 선택된 물고기 적용",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
"fish_ids": openapi.Schema(
type=openapi.TYPE_ARRAY,
items=openapi.Items(type=openapi.TYPE_INTEGER)
)
},
required=["fish_ids"]
),
responses={200: "Saved"}
)
def post(self, request, repo_id):
selected_ids = request.data.get("fish_ids", [])

try:
Fishtank.objects.get(repository_id=repo_id)
except Fishtank.DoesNotExist:
return Response({"detail": "Fishtank not found"}, status=404)

fishes = ContributionFish.objects.filter(
contributor__repository_id=repo_id
)

# 1) 선택되지 않은 물고기 → 숨김
fishes.exclude(id__in=selected_ids).update(is_visible=False)

# 2) 선택된 물고기 → 표시
fishes.filter(id__in=selected_ids).update(is_visible=True)

return Response({"detail": "Fishtank updated"}, status=200)