[TIL #54] 최종프로젝트 #3 Nested Serializer

안떽왕·2023년 6월 9일
0

Today I Learned

목록 보기
56/76

오늘까지 진행해서 기본적인 백엔드 작성은 마쳤습니다.
모델, 시리얼라이저, views까지 다 만들었고 post맨에서의 테스트도 성공적이였습니다.

다만 한가지 안되어있는 것이 있다면 Routes라는 모델에 들어가야하는 맵에서 찍은 장소에 대한 정보가 아직 Routes라는 여행 경로 모델에 들어가 있지 않습니다.

카카오맵을 처음 사용해봐서 어떤 정보를 어떻게 주는지 아직 모르기때문에 공란으로 만들어놓고 이제 카카오맵 api를 사용해보면서 어떻게 데이터를 주고 저장하게 할 것인지 고민해 보겠습니다.

그리고 오늘 있었던 에러를 소개하겠습니다.
오늘 겪은 에러는 Nested Serializer관련 에러였습니다.

Nested Serializer는 Serializer안에 또 다른 Serializer가 중첩되어 있는 형태입니다.

# 여행경로 작성, 수정
class RouteCreateSerializer(serializers.ModelSerializer):
    destinations = DestinationSerializer(many=True)
    places = PlaceSerializer(many=True)

    class Meta:
        model = Routes
        fields = ("title", "content", "image", "duration", "cost", "destinations", "places")

이전에 이와 같이 작성이 되어있었고 여행경로 작성을 테스트 해보니 Nested Serializer에서 중첩된 필드는 직접 값을 변경시킬 수 없고 readONLY를 해당 필드에 적용해주면 글 작성은 가능해지지만 readonly이기 때문에 해당 필드에 글을 작성해도 저장되지 않습니다.

이에 대한 해결책을 찾아본 결과 create나 update메서드를 오버라이딩 하는것이 해결책으로 나왔습니다.

class RouteCreateSerializer(serializers.ModelSerializer):
    destinations = DestinationSerializer(many=True)
    places = PlaceSerializer(many=True)

    class Meta:
        model = Routes
        fields = ("title", "content", "image", "duration", "cost", "destinations", "places")
    
    # drf에서는 중첩된 필드에 대해 조회만 가능하게 지원한다.
    # 그래서 입력값을 저장하기 위해 create, update메서드를 오버라이드 해줘야한다.    
    def create(self, validated_data):
        destinations_data = validated_data.pop('destinations', [])
        places_data = validated_data.pop('places', [])
        
        route = Routes.objects.create(**validated_data)
        
        for destination_data in destinations_data:
            Destinations.objects.create(route=route, **destination_data)
        
        for place_data in places_data:
            Places.objects.create(route=route, **place_data)
        
        return route    

create메서드를 별도로 만들어서 저장하니 중첩된 필드들도 모두 잘 저장할 수 있었습니다.

profile
이제 막 개발 배우는 코린이

0개의 댓글