티스토리 뷰

Django

[Django] Django Serializers

Gray__ 2022. 1. 16. 23:53

Django Rest Framework 

DRF를 공부했는데 정리가 필요한 것 같고 직접 간단히 실습하기 위해서 코드를 돌려봤습니다 !

joeylee.log 블로그를 참고하였습니다.

 

Pycharm을 이용해 newapi 프로젝트를 생성하고 python manage.py startapp news 명령어를 이용해

news 어플리케이션을 추가해줍니다 !

 

1. news/models.py 작성

class Article(models.Model):
    #author = models.ForeignKey(Journalist, on_delete=models.CASCADE, related_name="articles")
    author = models.CharField(max_length=120)
    title = models.CharField(max_length=120)
    description = models.CharField(max_length=200)
    body = models.TextField()
    location = models.CharField(max_length=120)
    publication_date = models.DateTimeField()
    active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True, null=True)
    updated_at = models.DateTimeField(auto_now=True, null=True)

    def __str__(self):
        return f"{ self.author } { self.title }"

Article 모델을 생성해주고 settings에 news를 추가합니다.

python manage.py makemigrations, migrate 명령어를 통해 모델을 추가합니다.

python manage.py createsuperuser 명령어를 통해 admin 계정을 생성한 후 임의의 모델 하나를 생성합니다 !

 

생성한 모델을 확인할 수 있습니다 !

 

 

2. news/api/serializers.py 작성

from rest_framework import serializers
from news.models import Article

class ArticleSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    author = serializers.CharField()
    title = serializers.CharField()
    description = serializers.CharField()
    body = serializers.CharField()
    location = serializers.CharField()
    publication_date = serializers.DateTimeField()
    active = serializers.BooleanField()
    created_at = serializers.DateTimeField(read_only=True)
    updated_at = serializers.DateTimeField(read_only=True)

    def create(self, validated_data):
        print(validated_data)
        return Article.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.author = validated_data.get('author', instance.author)
        instance.title = validated_data.get('title', instance.title)
        instance.description = validated_data.get('description', instance.description)
        instance.body = validated_data.get('body', instance.body)
        instance.location = validated_data.get('location', instance.location)
        instance.publication_date = validated_data.get('publication_data', instance.publication_date)
        instance.active = validated_data.get('active', instance.active)
        instance.save()
        return instance

 

 

 

3. python shell을 실행하여 결과 확인

 

1) Model instance를 Serialize

>>> from news.models import Article
>>> from news.api.serializers import ArticleSerializer

>>> article_instance = Article.objects.first()
>>> serializer = ArticleSerializer(article_instance)
>>> article_instance
<Article: HongGilDong 홍길동전>
>>> Article.objects.values()
<QuerySet [{'id': 1, 'author': 'HongGilDong', 'title': '홍길동전', 'description': '21세기 최고의 소설', 'body': '홍길동은 어떤 사람이었을까?', 'location': '부산시 부산진구 중앙대로 21 교
보문고', 'publication_date': datetime.datetime(2022, 1, 16, 14, 10, 2, tzinfo=<UTC>), 'active': True, 'created_at': datetime.datetime(2022, 1, 16, 14, 10, 9, 163973, tzinfo=<UTC>), 'upda
ted_at': datetime.datetime(2022, 1, 16, 14, 10, 9, 163973, tzinfo=<UTC>)}]>

>>> article_instance.author
'HongGilDong'
>>> serializer
ArticleSerializer(<Article: HongGilDong 홍길동전>):
    id = IntegerField(read_only=True)
    author = CharField()
    title = CharField()
    description = CharField()
    body = CharField()
    location = CharField()
    publication_date = DateTimeField()
    active = BooleanField()
    created_at = DateTimeField(read_only=True)
    updated_at = DateTimeField(read_only=True)
    
>>> serializer.data
{'id': 1, 'author': 'HongGilDong', 'title': '홍길동전', 'description': '21세기 최고의 소설', 'body': '홍길동은 어떤 사람이었을까?', 'location': '부산시 부산진구 중앙대로 21 교보문고', 'p
ublication_date': '2022-01-16T14:10:02Z', 'active': True, 'created_at': '2022-01-16T14:10:09.163973Z', 'updated_at': '2022-01-16T14:10:09.163973Z'}

Model Instance가 queryset을 반환하는 것을 볼 수 있다. 반환된 queryset을 Serializer를 이용하여 serializer.data를 출력해보면 dictionary 형태로 변환된 것을 알 수 있다.

 

2) Serialize화 하여 데이터 저장

> serializer = ArticleSerializer(data=data)

> serializer.is_valid()
True

# serializer로 객체에 데이터 저장하기
> serializer.validated_data
OrderedDict([('author', 'Jone doe'), ('title', 'How to be CEO'), ('description', "it's tough"), ('body', 'hahaha'), ('location', 'Seoul'), ('publication_date', datetime.datetime(2020, 7, 8, 9, 12, 41, tzinfo=<UTC>)), ('active', True)])
> serializer.save()
{'author': 'Jone doe', 'title': 'How to be CEO', 'description': "it's tough", 'body': 'hahaha', 'location': 'Seoul', 'publication_date': datetime.datetime(2020, 7, 8, 9, 12, 41, tzinfo=<UTC>), 'active': True}
<Article: Jone doe How to be CEO>

# 데이터 저장되었는지 확인
> Article.objects.all()
<QuerySet [<Article: Jone doe How to be CEO>, <Article: Jone doe How to be CEO>]

 

Serializers 공식 문서 요약

https://www.django-rest-framework.org/api-guide/serializers/

 

Serializers - Django REST framework

 

www.django-rest-framework.org

Comment Serializer를 선언한다. form을 선언하는 것과 비슷한 형태로 나타난다 !

from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

 


  • Serializing objects: GET 요청이 들어왔을 때, 객체를 가져와서 데이터를 보여줌
serializer = CommentSerializer(comment)
serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}

  • Deserializing objects: POST, PUT 등의 요청일 때, 데이터를 받아서 DB에 저장
serializer = CommentSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# {'content': 'foo bar', 'email': 'leila@example.com', 'created': datetime.datetime(2012, 08, 22, 16, 20, 09, 822243)}

serializer.is_valid() 함수를 이용해 데이터가 유효한지 유효성 검사를한 후, 데이터를 딕셔너리 형태로 변환한다


  • Saving instances: deserializing된 객체를 데이터에 저장
comment = serializer.save()

# .save() will create a new instance.
serializer = CommentSerializer(data=data)
serializer.save()

# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)
serializer.save()
댓글