All Articles

Django Rest Framework 활용하기 5 - The ModelSerializer Class

Udemy 강의를 들으면서, DRF 공식문서를 보면서, 그리고 구글링하면서 정리한 내용입니다.

Django REST Framework - Level One

The ModelSerializer Class

ModelSerializer는 장고 ModelForm 클래스와 비슷하게 내가 짠 모델을 바탕으로 Serializer를 쉽고 빠르게 짤 수 있게 해준다.

ModelSerializer의 가장 큰 장점은 코드 길이를 획기적으로 줄일 수 있다는 것과 api에 보내지길 원하는 필드를 선택할 수 있다는 점, 그리고 필드를 추가할 수 있다는 점이다.

ModelSerializer에서는 Serializer 방식처럼 필드를 하나하나 다 써줄 필요가 없다. 또한 create, update 메소드를 내장하고 있어서 코드 길이가 매우 짧다.

Serializer와 비교해서 코드를 얼마나 줄일 수 있는지 보자.

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.DateField()
  active = serializers.BooleanField()
  created_at = serializers.DateTimeField(read_only = True)
  updated_at = serializers.DateTimeField(read_only = True)

  def create(self, 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_date', instance.publication_date)
    instance.active = validated_data.get('active', instance.active)
    instance.save()
    return instance

ModelSerializer를 썼을 때는 아래와 같다.

class ArticleSerializer(serializers.ModelSerializer):

  class Meta:
    model = Article
    fields = "__all__"

Article 테이블 모든 필드를 불러오는 코드는 이게 끝이다. 처음 이 코드를 봤을 때 사기가 아닌가 생각했다. 새 article post도 되고 put도 된다.

출력할 필드 지정하기

ModelSerializer에서는 api에 표시할 필드를 지정할 수도 있다. 반대로 제외할 필드를 지정해도 된다.

class ArticleSerializer(serializers.ModelSerializer):

  class Meta:
    model = Article
    # 출력할 필드를 tuple 형태로 지정
    fields = ('title', 'description', 'body')
class ArticleSerializer(serializers.ModelSerializer):

  class Meta:
    model = Article
    # 제외할 필드를 tuple 형태로 지정
    exclude = ('id',)

validation 하기

validate 메소드도 그대로 사용할 수 있다. 설정한 조건(title과 description은 같으면 안 됨)에 맞지 않으면 인스턴스가 생성되지 않는다.

class ArticleSerializer(serializers.ModelSerializer):

  class Meta:
    model = Article
    exclude = ('id',)

  def validate(self, data):
    '''check that description and title are different'''
    if data['title'] == data['description']:
      raise serializers.ValidationError("Title and Description must be different from one another.")
    return data

  def validate_title(self, value):
    if len(value) > 60:
      raise serializers.ValidationError("The title has to be less than 60 characters long.")
    return value

인스턴스 생성 시각 관련 작업

article이 발행된 시간으로부터 얼마나 지났는지도 Json 형태로 같이 리턴할 수 있다. serializers.py를 건들여보자.

class ArticleSerializer(serializers.ModelSerializer):
  time_since_publication = serializers.SerializerMethodField()
  '''
  코드 후략
  '''

아래와 같이 발행 시점으로부터 며칠 혹은 몇 시간이 지났다고 값을 리턴한다.

{
  "time_since_publication": "3 hours, 30 minutes",
  // ...
}