Django RestFramework(2) - Serializer

Serializer
API는 JSON과 동작하고, Django는 파이썬과 동작한다.
JSON과 파이썬은 다른 언어고, 당연히 둘이 사용하는 객체 또한 다르다.
Django Restframework가 가지고 있는 Serializer는 이 둘 사이에서 변환하는 역할을 한다.
즉 장고에서 생성된 객체를 JSON형태로 바꿔주고, JSON형태로 들어온 객체를 파이썬 객체로 바꿔서
장고로 전달하는 역할을 한다.

Django => Serializer => JSON
JSON => Serializer => Django object
장고와 자바스크립트 사이의 다리 역할을 하는것이 Serializer라고 할 수 있다.

어떻게 사용하지?
serializer는 장고의 forms와 유사하게 볼 수 있다.
가지고 있는 모델을 가져와서 폼에 넣듯이, 모델의 필드들을 serializer에 넣는다고 생각하면 된다.

from datetime import datetime

class Comment(object):def __init__(self, email, content, created=None):self.email = email
        self.content = content
        self.created = created or datetime.now()comment = Comment(email='leila@example.com', content='foo bar')
from rest_framework import serializers

class CommentSerializer(serializers.Serializer):    email = serializers.EmailField()    content = serializers.CharField(max_length=200)    created = serializers.DateTimeField()
serializer = CommentSerializer(email='leila@example.com', content='foo bar')serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}

모델에 맞게 시리얼라이저를 생성하고, 맞는 모델을 넣게되면, JSON형태로 변환해주는 것을 확인해 볼 수 있다.
시리얼라이저에 의해 변환된 데이터는 serializer.data 라는 변수에 저장된다.

ModelSerializer
모델 시리얼라이저 라는 것을 제공해준다. 위에 기본 시리얼라이저에서 필드들을 직접 정의했는데, 
모델 시리얼라이저를 사용하면 필드를 지정할 필요없이 존재하는 모델을 가져와 모델 필드에 맞게 자동으로
필드를 만들어주는 시리얼라이저이다.
class AccountSerializer(serializers.ModelSerializer):    class Meta:        model = Account        fields = ('__all__')

메타 클래스를 사용해서 모델을 지정하고, 원하는 필드를 지정할 수 있다.
직접 지정하는것보다 간편하게 사용할 수 있다. 필드의 __all__ 옵션은 모든 필드를 지정하는 옵션이고,
직접 원하는 필드만 지정할 수 있다

Nested Serializer
어떤 모델들은 Relational Model 필드( ForeignKey, ManyToMany .. )를 가지고있다.이를 그냥 시리얼라이저로 처리해버리면, 그 필드에 해당되는 부분이 pk로 표시된다.이를 전체적으로 보고싶다면, 즉 오브젝트 안에서 다른 오브젝트의 정보를 표현하고 싶다면Nested Serializer를 사용한다

#modelsclass Category(models.Model):
    name = models.TextField()
class Post(models.Model):
    category = models.ForeignKey(Category)
    content = models.TextField()

#Serializer
class CategorySerializer(serializer.ModelSerializer):
    class Meta:
        model = Category
        fields = '__all__'
class PostSerializer(serializer.ModelSerializer):
    category = CategorySerializer()
    class Meta:
        model = Post
        fields = '__all__'

이렇게 관계를 가지는 부분의 시리얼라이저 필드를 따로 지정해주게 되면,
api 정보를 받아올때 그 부분에 관계를 가지는 모델의 객체를 받아오게된다.오브젝트 내에서 오브젝트의 데이터를 불러올때 간편하게 사용할 수 있다.
Django Hidden Model Field
장고에는 겉으로 명시되지 않는 히든필드가 존재한다. 
관계형 모델간에 생성되는 필드가 그것이다.
A 모델이 B 모델을 외래키로 가지게 되면, B모델은 자신을 외래키로 가지는 모든 A 모델을 가진 필드가 존재한다
그 필드를 보려면 디폴트값으로는 B.A_set.all() 이라는 필드를 통해서 볼 수 있다.
이를 시리얼라이저에서도 볼 수가 있는데, '__all__' 을 통해 모든 필드를 사용했을 경우에는 디폴트값으로 
히든필드가 다뤄지지않는다. 이를 위해서는 직접 필드를 지정해야한다
fields = (
    ...,
    'B_set',
)
이런식으로 사용 할 수 있고, nested serializer 방식으로 그 객체의 모든 데이터를 출력하는것도 가능하다.

댓글