약속
생성
시리얼라이저
class EventCreateSerializer(serializers.Serializer):
"""약속 생성을 위해 클라이언트가 보내는 데이터를 검증하는 클래스"""
title = serializers.CharField(max_length=100)
is_business = serializers.BooleanField(default=False)
서비스
class EventService:
"""약속 자체와 관련된 핵심 로직을 담당하는 서비스 클래스"""
def create_event(validated_data, user):
event = Event.objects.create(
title=validated_data["title"],
is_business=validated_data.get("is_business", False),
host=user
)
EventMember.objects.create(event=event, user=user, can_invite=True)
return event
뷰
def post(self, request):
serializer = EventCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
event = EventService.create_event(serializer.validated_data, request.user)
return Response(
{"message": "약속이 성공적으로 생성되었습니다."},
status=status.HTTP_201_CREATED,
)
테스트

초대
serializer
class EventMemberManageSerializer(serializers.Serializer):
"""약속 참여자를 관리(초대, 권한부여, 강퇴)할 때 필요한 데이터를 검증하는 클래스"""
target_user_id = serializers.IntegerField()
service
class EventMemberService:
"""약속 내부의 참여자들을 관리하는 로직을 담당하는 서비스 클래스"""
def invite_user(event_id, target_user_id, request_user):
event = get_object_or_404(Event, id=event_id)
inviter = get_object_or_404(EventMember, event=event, user=request_user)
if event.host == request_user or inviter.can_invite:
User = get_user_model()
target_user = get_object_or_404(User, id=target_user_id)
EventMember.objects.create(event=event, user=target_user)
return True
return False
view
class EventInviteView(APIView):
"""초대 기능만을 전담하는 뷰 클래스"""
permission_classes = [IsAuthenticated]
@extend_schema(tags=["참여자관리"], summary="약속 초대", request=EventMemberManageSerializer)
def post(self, request, event_id):
serializer = EventMemberManageSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
target_user_id = serializer.validated_data["target_user_id"]
success = EventMemberService.invite_user(event_id, target_user_id, request.user)
if success:
return Response({"message": "성공적으로 초대했습니다."}, status=status.HTTP_200_OK)
return Response({"message": "초대 권한이 없습니다."}, status=status.HTTP_403_FORBIDDEN)
테스트

초대 권한
service
class EventMemberService:
"""약속 내부의 참여자들을 관리하는 로직을 담당하는 서비스 클래스"""
...
def grant_permission(event_id, target_user_id, request_user):
event = get_object_or_404(Event, id=event_id)
if event.host == request_user:
target_member = get_object_or_404(EventMember, event=event, user_id=target_user_id)
target_member.can_invite = True
target_member.save()
return True
return False
view
class EventGrantPermissionView(APIView):
"""권한 부여 기능만을 전담하는 뷰 클래스"""
permission_classes = [IsAuthenticated]
@extend_schema(tags=["약속관리"], summary="초대 권한 부여", request=EventMemberManageSerializer)
def post(self, request, event_id):
serializer = EventMemberManageSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
target_user_id = serializer.validated_data["target_user_id"]
success = EventMemberService.grant_permission(event_id, target_user_id, request.user)
if success:
return Response({"message": "초대 권한이 부여되었습니다."}, status=status.HTTP_200_OK)
return Response({"message": "권한 부여는 방장만 가능합니다."}, status=status.HTTP_403_FORBIDDEN)
테스트

멤버 강퇴
service
def kick_user(event_id, target_user_id, request_user):
"""약속 방에서 특정 인원을 강제로 내보내는 메서드"""
event = get_object_or_404(Event, id=event_id)
if event.host == request_user:
target_member = get_object_or_404(EventMember, event=event, user_id=target_user_id)
target_member.delete()
return True
return False
view
class EventKickView(APIView):
"""멤버 강퇴 기능만을 전담하는 뷰 클래스"""
permission_classes = [IsAuthenticated]
@extend_schema(tags=["약속관리"], summary="멤버 강퇴", request=EventMemberManageSerializer)
def post(self, request, event_id):
serializer = EventMemberManageSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
target_user_id = serializer.validated_data["target_user_id"]
success = EventMemberService.kick_user(
event_id, target_user_id, request.user
)
if success:
return Response(status=status.HTTP_204_NO_CONTENT)
return Response({"message": "강퇴는 방장만 가능합니다."}, status=status.HTTP_403_FORBIDDEN)
테스트

오늘의 작업
