API의 응답 형태에 변화를 줄 수 있는 ModelSerializer 내장 메서드
예를 들어 아래와 같은 테이블이 있다고 가정합시다.
- 게시글 ( Post ) 과 게시글의 이미지 ( PostImage )들 > PostImages
- M : N 관계
- 게시글 ( Post )의 태그 ( Tag )들 > PostTags
- M : N 관계
- 이미지 ( PostImage )의 태그 ( Tag )들 > PostImageTags
- M : N 관계
class TagSerializer(ModelSerializer):
class Meta:
model = tag_models.Tag
fields = ("pk", "tag_name",)
class PostImageTagsSerializer(ModelSerializer):
class Meta:
model = tag_models.Tag
fields = ("pk", "tag_name",)
class PostImageSerializer(ModelSerializer):
class Meta:
model = post_models.PostImage
fields = ("pk", "url",)
class PostImagesSerializer(ModelSerializer):
image = PostImageSerializer()
tags = PostImageTagsSerializer(many=True)
class Meta:
model = post_models.PostImages
fields = ("pk", "image", "tags",)
class PostSerializer(ModelSerializer):
post_tags = TagSerializer(many=True)
images = PostImagesSerializer(source="post_images", many=True)
class Meta:
model = post_models.Post
fields = ("pk", "title", "post_tags", "images",)
{
"pk":1,
"title":"즐거운 하루",
"post_tags":[
{
"pk":1,
"tag_name":"태그 이름"
},
{
"pk":2,
"tag_name":"태그 이름"
}
],
"images":[
{
"pk":1,
"image":{
"pk":1,
"url":"이미지 주소"
},
"tags":[
{
"pk":3,
"tag_name":"태그 이름"
},
{
"pk":4,
"tag_name":"태그 이름"
}
]
}
]
}
"images":[
{
"pk":1,
"""""""""""""""
""" 여기부터 """
"image":{
"pk":1,
"url":"이미지 주소"
},
""" 여기까지 """
"""""""""""""""
"tags":[
{
"pk":3,
"tag_name":"태그 이름"
},
{
"pk":4,
"tag_name":"태그 이름"
}
]
}
]
{
"images":[
{
"pk":1,
"url":"이미지 주소",
"tags":[
{
"pk":3,
"tag_name":"태그 이름"
},
{
"pk":4,
"tag_name":"태그 이름"
}
]
},
]
}
def to_representation(self, instance):
# 변하기 전 원래 응답 형태를 그대로 가져온다.
representation = super().to_representation(instance)
tag_json = {}
image = {}
# 기존 응답형태를 key, value로 루프
for key, val in representation.items():
if key == "tags":
tag_json = val
elif key == "image":
tmp = {
**val,
"tags": []
}
image = tmp
image["tags"] = tag_json
# 기존 응답 형태를 새로운 응답형태로 치환
representation = image
# 치환된 응답 형태를 반환
return representation