[Django] POST api - 참조하기도 하하고, 참조되기도 하는 모델 create

Seaniiio·2024년 7월 18일
0

Django

목록 보기
3/5

내 기준 복잡한 구조를 갖는 모델에 대한 create api를 구현했다.

모델 설명

이 게시물에서 설명할 api는 Dog를 create하는 api이다.

Dog 모델의 특징은 다음과 같다.

  • User를 참조한다.
  • DogTag로부터 참조된다.

여기서 강아지 한 마리는 여러 개의 태그를 가질 수 있다.

코드 설명

input data

우선 강아지를 등록하기 위해 전해주는 json 데이터의 예시는 아래와 같다.

{
	"dog" : {
        "name" : "제제",
        "gender" : "M",
        "age" : 12,
        "introduction" : "활발한데 오래 걷지는 못해요"
	},
    "tags" : [
		{
          "number": 1
	    },
	    {
          "number": 3
	    }
    ]
}
  • dog에는 등록할 Dog에 대한 내용이 담겨있다.
  • tags에는 그 Dog에 대한 태그들이 배열로 담겨있다.
  • Dog, DogTag를 생성할 때 꼭 필요한 필드들만 담겨있다.

serializer.py

class DogSerializer(serializers.ModelSerializer):
    class Meta:
        model = Dog
        fields = ('name', 'gender', 'age', 'introduction')

class DogTagSerializer(serializers.ModelSerializer):
    class Meta:
        model = DogTag
        fields = ('number',)
  • 우선 Dog, DogTag에 대한 ModelSerializer을 만들어준다.
  • class Meta에서 Dog, DogTag를 만들기 위해 꼭 필요한 정보만을 필드로 추가한다.
class DogRegisterSerializer(serializers.Serializer):
    dog = DogSerializer()
    tags = DogTagSerializer(many=True)

    def create(self, validated_data):
        dog_data = validated_data['dog']
        user = self.context['request'].user  # JWT 인증을 통해 로그인된 사용자 정보 가져오기

        dog = Dog.objects.create(user_id=user, **dog_data) # dog 객체 생성

        if 'tags' in validated_data:
            tags_data = validated_data['tags']

            for tag_data in tags_data:
                DogTag.objects.create(dog_id=dog, **tag_data)
            
        return dog
  • Dog 모델과 DogTag 모델의 데이터를 함께 처리할 수 있도록 만든 Serializer이다.
  • Tag는 여러개가 될 수 있기 때문에, many=True 속성을 추가한다.

Dog 생성

  • dog_data에는 사용자가 입력한 Dog에 대한 데이터들이 담겨있다.
  • 그런데 Dog에는 dog_data뿐만 아니라, foreign key인 user_id도 필요하다.
  • view에서 받아온 토큰을 기반으로 현재 로그인되어 있는 유저에 대한 user 객체를 얻는다.
  • Dog을 create할 때 user 객체 정보까지 포함시킨다.

DogTag 생성

  • tags에 여러개의 태그를 입력할 수 있으므로, for문을 돌린다.
  • DogTag에는 tag_data뿐만 아니라, 참조하는 dog에 대한 정보도 필요한데, 이미 위에서 구했기 때문에 dog 객체를 넘겨준다.

views.py

@api_view(['POST'])
@authentication_classes([JWTAuthentication])
def new_dog(request):
    serializer = DogRegisterSerializer(data=request.data, context={'request': request})

    if serializer.is_valid():
        serializer.save()
        return Response({"message" : "강아지가 등록되었습니다."},status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=400)
  • serializer에 request로 받은 데이터를 넘겨준다.
  • context={'request': request}는 현재 HTTP 요청 객체를 직렬화 클래스에 전달하는 부분이다.
  • serializer에서 self.context['request'].user를 통해 현재 인증된 사용자를 참조할 수 있다.(user_id가 필요하기 때문에 보내준다.)

테스트



잘 등록되는 것을 확인할 수 있다!

0개의 댓글