2026/05/08

김기훈·2026년 5월 8일

TIL

목록 보기
193/194

오랜만에 다시하기 때문에 이론도 함께 공부


약속 생성 재테스트


단일 약속 조회

시리얼라이저

  • 복잡한 데이터베이스 객체(파이썬 객체)를 웹이나 모바일 통신에 적합한 JSON 같은 텍스트 형식으로
    • 직렬화해주는 핵심 구성 요소
  • 프론트엔드와 백엔드가 서로 다른 개발 언어를 사용하더라도
    • JSON이라는 공통 언어로 소통할 수 있도록 번역기 역할을 담당
class EventRetrieveSerializer(serializers.ModelSerializer):
    """조회 응답에 사용할 데이터를 검증하는 클래스를"""
    class Meta:
        model = Event
        # 클라이언트에게 보여줄 항목들을 리스트로 지정
        fields = ['id', 'title', 'is_business', 'host', 'created_at']

서비스

class EventQueryService:
    """약속 조회를 전담할 서비스 클래스"""
    # 1. 객체 생성 없이 메서드를 바로 사용할 수 있도록 데코레이터
    @staticmethod
    def get_event(event_id):
        """조회할 약속의 고유 아이디를 전달받는 함수"""
        # 2. 전달받은 아이디로 약속을 찾고, 없으면 에러를 발생시킴
        event = get_object_or_404(Event, id=event_id)
        return event

class EventListView(APIView):
    """단일 약속 조회를 처리할 API 뷰 클래스를 선언"""

    permission_classes = [IsAuthenticated]

    @extend_schema(
        tags=["약속조회"], summary="단일 약속 조회", responses=EventListSerializer
    )
    def get(self, request, event_id):
        """클라이언트가 데이터 조회를 위해 HTTP GET 방식으로 요청했을 때 실행되는 함수"""
        # 1. 서비스를 통해 요청받은 아이디의 약속 정보를 데이터베이스에서 가져옴
        event = EventQueryService.get_event(event_id)
        # 2. 가져온 데이터를 시리얼라이저에 넣어 변환을 시작
        serializer = EventListSerializer(event)
        return Response(serializer.data, status=status.HTTP_200_OK)

스웨거 테스트


전체 약속 조회

시리얼라이저

class EventAllListSerializer(serializers.ModelSerializer):
    """목록 조회를 위해 꼭 필요한 필드만 선택하여 간결하게 구성한 클래스"""

    # 방장의 정보를 단순히 아이디 숫자가 아닌 이름(username)으로 보여주기 위해 추가
    host_name = serializers.CharField(source='host.username', read_only=True)

    class Meta:
        model = Event
        # 클라이언트에게 보여줄 항목들을 리스트로 지정
        fields = ['id', 'title', 'host_name', 'is_business', 'created_at']

서비스

    def get_all_user_events(user):
        """사용자가 방장이거나 멤버로 참여 중인 모든 약속을 찾는 함수"""
        # 2. host가 나인 경우 OR 2. 멤버 목록(eventmember)에 내가 포함된 경우를 모두 찾기
        return Event.objects.filter(
            # 3. OR 조건을 처리하기 위해 장고의 Q 객체 사용
            Q(host=user) | Q(eventmember__user=user)
        ).distinct().order_by('-created_at')

——————————————————————————————————————[비교]—————————————————————————————————————————
    def get_all_user_events(user):
        """사용자가 방장이거나 멤버로 참여 중인 모든 약속을 찾는 함수"""
        # 2. host가 나인 경우 OR 2. 멤버 목록(eventmember)에 내가 포함된 경우를 모두 찾기
        return Event.objects.filter(
            # 3. OR 조건을 처리하기 위해 장고의 Q 객체 사용
            Q(host=user) | Q(members__user=user)
        ).distinct().order_by('-created_at')

class EventAllListView(APIView):
    """내 모든 약속 목록을 반환하는 API 뷰"""

    permission_classes = [IsAuthenticated]

    @extend_schema(
        tags=["약속조회"], summary="내 모든 약속 목록 조회", responses=EventAllListSerializer(many=True)
    )
    def get(self, request):
        # 1. 서비스 로직을 호출하여 내가 연관된 모든 약속 데이터를 가져옴
        events = EventQueryService.get_all_user_events(request.user)
        # 2. 가져온 데이터를 시리얼라이저에 넣어 변환을 시작
        serializer = EventAllListSerializer(events, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

문제 해결

  • 전체 약속 조회 기능에서 500에러 발생

    • 원인: 필터링 조건인 Q(eventmember__user=user) 부분
    • EventMember모델에서 event 필드에 related_name="members" 속성을 추가했음
    • 해결: Q(members__user=user) 로 필터링 조건을 수정

스웨거 테스트


디자인 도입

뷰 연결

def list_promise(request):
    """전체 약속 목록 페이지(HTML)를 연결해주는 함수를 정의"""
    return render(request, "event/list.html")

def detail_promise(request, event_id):
    """단일 약속 상세 페이지(HTML)를 연결해주는 함수를 정의"""
    return render(request, "event/detail.html")

url 연결

urlpatterns = [
				...
    path("list-page/", list_promise, name="list_page"),
    path("<int:event_id>/detail-page/", detail_promise, name="detail_page"),
]

디자인 테스트

  • 내 약속 목록

  • 약속 상세 조회


내일 해야 할 일

  • 약속 가능 시간 지정하는 기능 구현
    • 24시간중 선택하여 교집합을 찾는 기능을 구현한다
profile
안녕하세요.

0개의 댓글