Skip to content

Commit 072f280

Browse files
committed
fix: 변경된 세션 모델을 serializer들에도 반영
1 parent 998dc63 commit 072f280

File tree

5 files changed

+72
-86
lines changed

5 files changed

+72
-86
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django_filters import rest_framework as filters
2+
3+
4+
class PresentationCategoryAdminFilterSet(filters.FilterSet):
5+
type = filters.UUIDFilter(field_name="type_id")
6+
7+
8+
class PresentationAdminFilterSet(filters.FilterSet):
9+
type = filters.UUIDFilter(field_name="type_id")
10+
11+
12+
class PresentationSpeakerAdminFilterSet(filters.FilterSet):
13+
presentation = filters.UUIDFilter(field_name="presentation_id")

app/admin_api/serializers/event/presentation.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
from core.serializer.base_abstract_serializer import BaseAbstractSerializer
33
from core.serializer.json_schema_serializer import JsonSchemaSerializer
44
from event.presentation.models import Presentation, PresentationCategory, PresentationSpeaker, PresentationType
5+
from file.models import PublicFile
56
from rest_framework import serializers
7+
from user.models import UserExt
68

79

810
class PresentationTypeAdminSerializer(BaseAbstractSerializer, JsonSchemaSerializer, serializers.ModelSerializer):
@@ -18,12 +20,43 @@ class Meta:
1820

1921

2022
class PresentationAdminSerializer(BaseAbstractSerializer, JsonSchemaSerializer, serializers.ModelSerializer):
23+
class PresentationCategoryField(serializers.PrimaryKeyRelatedField):
24+
def get_queryset(self):
25+
qs = super().get_queryset()
26+
return qs.filter(type=self.instance.type) if self.instance else qs.none()
27+
28+
categories = PresentationCategoryField(
29+
many=True, required=False, queryset=PresentationCategory.objects.filter_active()
30+
)
31+
2132
class Meta:
2233
model = Presentation
23-
fields = COMMON_ADMIN_FIELDS + ("title_ko", "title_en")
34+
fields = COMMON_ADMIN_FIELDS + (
35+
"categories",
36+
"type",
37+
"title_ko",
38+
"title_en",
39+
"description_ko",
40+
"description_en",
41+
)
42+
43+
def validate(self, attrs: dict) -> dict:
44+
type = attrs.get("type", getattr(self.instance, "type", None))
45+
categories = attrs.get("categories", getattr(self.instance, "categories", []))
46+
47+
if type and categories:
48+
if not all(category.type == type for category in categories):
49+
raise serializers.ValidationError("All categories must belong to the same type.")
50+
51+
return super().validate(attrs)
2452

2553

2654
class PresentationSpeakerAdminSerializer(BaseAbstractSerializer, JsonSchemaSerializer, serializers.ModelSerializer):
55+
user = serializers.PrimaryKeyRelatedField(queryset=UserExt.objects.filter(is_active=True))
56+
image = serializers.PrimaryKeyRelatedField(
57+
queryset=PublicFile.objects.filter_active(), allow_null=True, required=False
58+
)
59+
2760
class Meta:
2861
model = PresentationSpeaker
29-
fields = COMMON_ADMIN_FIELDS + ("presentation", "user", "biography_ko", "biography_en")
62+
fields = COMMON_ADMIN_FIELDS + ("presentation", "user", "image", "biography_ko", "biography_en")

app/admin_api/urls.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from admin_api.views.event.event import EventAdminViewSet
33
from admin_api.views.event.presentation import (
44
PresentationAdminViewSet,
5+
PresentationCategoryAdminViewSet,
56
PresentationSpeakerAdminViewSet,
67
PresentationTypeAdminViewSet,
78
)
@@ -28,11 +29,9 @@
2829
admin_event_router.register("sponsortag", SponsorTagAdminViewSet)
2930
admin_event_router.register("sponsor", SponsorAdminViewSet)
3031
admin_event_router.register("presentationtype", PresentationTypeAdminViewSet)
32+
admin_event_router.register("presentationcategory", PresentationCategoryAdminViewSet)
3133
admin_event_router.register("presentation", PresentationAdminViewSet)
32-
admin_event_router.register(
33-
"presentation/(?P<presentation_id>{UUID_V4_PATTERN})/speaker",
34-
PresentationSpeakerAdminViewSet,
35-
)
34+
admin_event_router.register("presentationspeaker", PresentationSpeakerAdminViewSet)
3635

3736
urlpatterns = [
3837
path("cms/", include(admin_cms_router.urls)),
Lines changed: 15 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
from __future__ import annotations
22

3+
from admin_api.filtersets.event.presentation import (
4+
PresentationAdminFilterSet,
5+
PresentationCategoryAdminFilterSet,
6+
PresentationSpeakerAdminFilterSet,
7+
)
38
from admin_api.serializers.event.presentation import (
49
PresentationAdminSerializer,
510
PresentationCategoryAdminSerializer,
611
PresentationSpeakerAdminSerializer,
712
PresentationTypeAdminSerializer,
813
)
9-
from core.const.regex import UUID_V4_PATTERN
1014
from core.const.tag import OpenAPITag
1115
from core.permissions import IsSuperUser
1216
from core.viewset.json_schema_viewset import JsonSchemaViewSet
13-
from django.db import models
1417
from drf_spectacular.utils import extend_schema, extend_schema_view
1518
from event.presentation.models import (
1619
Presentation,
1720
PresentationCategory,
18-
PresentationCategoryRelation,
1921
PresentationSpeaker,
2022
PresentationType,
2123
)
22-
from rest_framework import decorators, exceptions, request, response, status, viewsets
24+
from rest_framework import viewsets
2325

2426
ADMIN_METHODS = ["list", "retrieve", "create", "update", "partial_update", "destroy"]
2527

@@ -31,92 +33,29 @@ class PresentationTypeAdminViewSet(JsonSchemaViewSet, viewsets.ModelViewSet):
3133
permission_classes = [IsSuperUser]
3234
queryset = PresentationType.objects.filter_active().select_related("created_by", "updated_by", "deleted_by")
3335

34-
@extend_schema(
35-
tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION],
36-
responses={status.HTTP_200_OK: PresentationCategoryAdminSerializer(many=True)},
37-
)
38-
@decorators.action(detail=True, methods=["get"], url_path="categories")
39-
def list_categories(self, *args: tuple, **kwargs: dict) -> response.Response:
40-
categories = PresentationCategory.objects.filter_active().filter(type=self.get_object())
41-
return response.Response(data=PresentationCategoryAdminSerializer(instance=categories, many=True).data)
42-
43-
@extend_schema(
44-
tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION],
45-
request=PresentationCategoryAdminSerializer,
46-
responses={status.HTTP_201_CREATED: PresentationCategoryAdminSerializer},
47-
)
48-
@decorators.action(detail=True, methods=["post"], url_path="categories")
49-
def add_category(self, request: request.Request, *args: tuple, **kwargs: dict) -> response.Response:
50-
serializer = PresentationCategoryAdminSerializer(data=request.data)
51-
serializer.is_valid(raise_exception=True)
52-
serializer.save()
53-
return response.Response(data=serializer.data, status=status.HTTP_201_CREATED)
54-
55-
@extend_schema(
56-
tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION],
57-
request=PresentationCategoryAdminSerializer,
58-
responses={status.HTTP_200_OK: PresentationCategoryAdminSerializer},
59-
)
60-
@decorators.action(detail=True, methods=["patch"], url_path=f"categories/(?P<category_id>{UUID_V4_PATTERN})")
61-
def update_category(self, request: request.Request, pk: str, category_id: str, *args, **kwargs):
62-
if not (category := PresentationCategory.objects.filter_active().filter(type_id=pk, id=category_id).first()):
63-
raise exceptions.NotFound(detail="Category not found.")
64-
65-
serializer = PresentationCategoryAdminSerializer(instance=category, data=request.data, partial=True)
66-
serializer.is_valid(raise_exception=True)
67-
serializer.save()
68-
return response.Response(data=serializer.data)
6936

70-
@extend_schema(tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION], responses={status.HTTP_204_NO_CONTENT: None})
71-
@decorators.action(detail=True, methods=["delete"], url_path=f"categories/(?P<category_id>{UUID_V4_PATTERN})")
72-
def delete_category(self, pk: str, category_id: str, *args: tuple, **kwargs: dict) -> response.Response:
73-
if not (category := PresentationCategory.objects.filter_active().filter(type_id=pk, id=category_id).first()):
74-
raise exceptions.NotFound(detail="Category not found.")
75-
76-
category.delete()
77-
return response.Response(status=status.HTTP_204_NO_CONTENT)
37+
@extend_schema_view(**{m: extend_schema(tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION]) for m in ADMIN_METHODS})
38+
class PresentationCategoryAdminViewSet(JsonSchemaViewSet, viewsets.ModelViewSet):
39+
http_method_names = ["get", "post", "patch", "delete"]
40+
serializer_class = PresentationCategoryAdminSerializer
41+
permission_classes = [IsSuperUser]
42+
filterset_class = PresentationCategoryAdminFilterSet
43+
queryset = PresentationCategory.objects.filter_active().select_related("created_by", "updated_by", "deleted_by")
7844

7945

8046
@extend_schema_view(**{m: extend_schema(tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION]) for m in ADMIN_METHODS})
8147
class PresentationAdminViewSet(JsonSchemaViewSet, viewsets.ModelViewSet):
8248
http_method_names = ["get", "post", "patch", "delete"]
8349
serializer_class = PresentationAdminSerializer
8450
permission_classes = [IsSuperUser]
51+
filterset_class = PresentationAdminFilterSet
8552
queryset = Presentation.objects.get_all_nested_data().select_related("created_by", "updated_by", "deleted_by")
8653

87-
@extend_schema(
88-
tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION],
89-
responses={status.HTTP_200_OK: PresentationCategoryAdminSerializer(many=True)},
90-
)
91-
@decorators.action(detail=True, methods=["get"], url_path="categories")
92-
def list_categories(self, *args: tuple, **kwargs: dict) -> response.Response:
93-
categories = self.get_object().active_categories
94-
return response.Response(data=PresentationCategoryAdminSerializer(instance=categories, many=True).data)
95-
96-
@extend_schema(tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION], responses={status.HTTP_201_CREATED: None})
97-
@decorators.action(detail=True, methods=["post"], url_path="categories/(?P<category_id>{UUID_V4_PATTERN})")
98-
def add_category(self, pk: str, category_id: str, *args: tuple, **kwargs: dict) -> response.Response:
99-
PresentationCategoryRelation.objects.get_or_create(presentation_id=pk, category_id=category_id)
100-
return response.Response(status=status.HTTP_201_CREATED)
101-
102-
@extend_schema(tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION], responses={status.HTTP_204_NO_CONTENT: None})
103-
@decorators.action(detail=True, methods=["delete"], url_path="categories/(?P<category_id>{UUID_V4_PATTERN})")
104-
def remove_category(self, pk: str, category_id: str, *args: tuple, **kwargs: dict) -> response.Response:
105-
if not (
106-
relation := PresentationCategoryRelation.objects.filter(presentation_id=pk, category_id=category_id).first()
107-
):
108-
raise exceptions.NotFound(detail="Category is not associated with this presentation.")
109-
110-
relation.delete()
111-
return response.Response(status=status.HTTP_204_NO_CONTENT)
112-
11354

11455
@extend_schema_view(**{m: extend_schema(tags=[OpenAPITag.ADMIN_EVENT_PRESENTATION]) for m in ADMIN_METHODS})
11556
class PresentationSpeakerAdminViewSet(JsonSchemaViewSet, viewsets.ModelViewSet):
11657
http_method_names = ["get", "post", "patch", "delete"]
11758
serializer_class = PresentationSpeakerAdminSerializer
11859
permission_classes = [IsSuperUser]
60+
filterset_class = PresentationSpeakerAdminFilterSet
11961
queryset = PresentationSpeaker.objects.filter_active().select_related("created_by", "updated_by", "deleted_by")
120-
121-
def get_queryset(self) -> models.QuerySet[PresentationSpeaker]:
122-
return super().get_queryset().filter(presentation_id=self.kwargs["presentation_id"])

app/event/presentation/serializers.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ class Meta:
1010

1111
class PresentationSpeakerSerializer(serializers.ModelSerializer):
1212
nickname = serializers.CharField(source="user.nickname", read_only=True)
13+
image = serializers.FileField(source="image.file", read_only=True, allow_null=True)
1314

1415
class Meta:
1516
model = PresentationSpeaker
16-
fields = ("id", "nickname", "biography")
17+
fields = ("id", "nickname", "biography", "image")
1718

1819

1920
class PresentationSerializer(serializers.ModelSerializer):
20-
categories = PresentationCategorySerializer(source="active_categories", many=True, read_only=True)
21-
speakers = PresentationSpeakerSerializer(source="active_speakers", many=True, read_only=True)
21+
image = serializers.FileField(source="image.file", read_only=True, allow_null=True)
22+
categories = PresentationCategorySerializer(many=True, read_only=True)
23+
speakers = PresentationSpeakerSerializer(many=True, read_only=True)
2224

2325
class Meta:
2426
model = Presentation
25-
fields = ("id", "title", "categories", "speakers")
27+
fields = ("id", "title", "description", "image", "categories", "speakers")

0 commit comments

Comments
 (0)