[DRF] 인스타그램 클론코딩하기-Serializer

Cherry·2022년 1월 26일
0
post-thumbnail
post-custom-banner

DRF이란?

Django 안에서 RESTful API 서버를 쉽게 구축할 수 있도록 도와주는 오픈소스 라이브러리이다.

DRF

  • HTTP 요청에 맞는 url patterns가 Views로 전달된다.
  • Serializer의 도움으로 Views는 HTTP 요청을 처리하고 HTTP 응답을 반환한다.
  • Serializer는 모델 객체를 serialize/deserialize 한다.
    • serialize : 직렬화, 프로그램의 객체에 담긴 데이터를 외부파일에 문자열 형태로 전송
    • deserialize : 역직렬화, 외부 파일의 데이터를 프로그램 내의 객체로 읽어오는 것
  • 모델에는 DB와 함께 CRUD 작업을 위한 필수 필드 및 동작이 포함되어 있다.

Serializer

serializer

Serializer는 우리가 Django 에서 사용하는 파이썬 객체나 queryset 같은 복잡한 객체들을 REST API에서 사용할 json 과 같은 형태로 변환해주는 어댑터 역할을 한다.

Serializer를 만들 때, 각 필드를 하나하나 정의해 주어야 한다. 마치 모델을 다시 한 번 작성하는 것 같은 불편함이 있었다. 이 문제를 해결해 주는 것이 ModelSerializer이다.

ModelSerializer

ModelSerializer는 크게 아래와 같은 3가지 기능을 제공한다. 주는 편리함이 워낙 크기에 Base Serializer보다 훨씬 생산성을 높일 수 있다.

  • 의존하고 있는 모델에 기반해서 Serializer 필드를 자동으로 만들어 준다
  • Serializer를 위한 validator 제공
  • .create(), .update() 함수 기본으로 제공하여 다시 만들 필요 없다.

ModelSerializer 사용 방법

  1. class Meta 작성

    • model = 모델명
    • fields = all, exclude, 직접 명시 ('id', 'name')
    • read_only_field = ['id']

2) serializer로 정의해 줘야 되는 필드

  • 추가하고 싶은 필드가 있을 경우, serializer.SerializerMethodField()로 정의해 준다.
  • ForeginKey로 연결된 필드가 있을 경우, Nested Serializer를 사용하여 ForeignKey로 연결된 필드의 pk를 가져온다.

ORM을 통해 데이터 조회

>>> from api.models import User, Profile,Post, Comment, Like
>>> Post.objects.all()
<QuerySet [<Post: chaeri : first>, <Post: chaeri : second>, <Post: choco : 배고파>, <Post: ceos : 세오스>]>
>>> Comment.objects.all()
<QuerySet [<Comment: choco commented ceos post>, <Comment: chaeri commented ceos post>, <Comment: choco commented ceos post>]>
>>> Like.objects.all()
<QuerySet [<Like: chaeri liked 세오스>, <Like: choco liked 세오스>, <Like: ceos liked 세오스>]>

Serializers

from rest_framework import serializers
from .models import *


class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        fields = '__all__'


class LikeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Like
        fields = '__all__'


class CommentSerializer(serializers.ModelSerializer):
    writer_nickname = serializers.SerializerMethodField()

    class Meta:
        model = Comment
        fields = ['post', 'writer', 'content', 'created_at', 'updated_at', 'writer_nickname']


    def get_writer_nickname(self,obj):
        return obj.writer.nickname


class PostSerializer(serializers.ModelSerializer):
    author_nickname = serializers.SerializerMethodField()
    post_like = LikeSerializer(many=True, read_only=True, source="like_set")
    post_comment = CommentSerializer(many=True, read_only=True, source="comment_set")
    
    class Meta:
        model = Post
        fields = ['author', 'title', 'content', 'author_nickname',
                  'created_at', 'updated_at', 'post_like', 'post_comment']

    def get_author_nickname(self, obj):
        return obj.author.nickname


class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ['user', 'nickname', 'introduction']

마주한 에러

처음 api를 테스트 했을 때 몇몇 데이터들이 넘어오지 않았다. 구글링 해보니 source argument를 넣어주지 않아서 그랬다.

예를 들어 Post객체 하나를 생성해보면

p = Post.objects.get(pk=1)

이제 이 post와 관련된 댓글들의 queryset은 다음과 같이 될것이다.

Comment.objects.filter(post=p)

이를 장고는 다음과 같이 단순화 할 수 있다.

p.comment_set

따라서 drf는 필드 이름에서 모델 속성을 찾기 때문에 source argument를 사용하여 Serializer가 데이터를 가져올 위치를 지정해주어야 한다.

Django Rest Framework를 이번에 처음 사용해보는데 확실히 다른 프레임워크에 비해 편리하게 코드를 구현할 수 있도록 만들어주는 프레임워크인것 같다. 유저친화적인 프레임워크인것 같다.👍👍

post-custom-banner

0개의 댓글