All Articles

Django Rest Framework 활용하기 4 - Serializers Validation

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

Django REST Framework - Level One

Serializers Validation

DRF는 여러 가지 validator를 제공한다. 하지만 built-in validator들이 모든 케이스를 커버하지 못하기 때문에 필요한 상황에 맞춰 custom validator를 짜야한다.

참고
Object level validation
필드 여러 개를 검증하는 것을 말한다. 만들었던 모델을 예로 들면, 특정 article의 title, author 모두를 확인하는 것이 object level validation이다.

Field level validation
반면 field level validation은 단일 필드만 검증하는 방법이다.

우선 “title” 항목과 “description” 항목의 값(value)이 똑같을 때 에러를 발생시키는 validator를 짜보자. 두 필드를 가지고 validation을 하는 것이므로 object level validation에 해당한다.

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

이런 serializers.py가 있다. 시리얼라이저 클래스 하단에 validate 메소드를 작성한다.

def validate(self, data):
  '''check that description and title are different'''
  # title과 description 값이 같으면 ValidationError를 일으킨다.
  # 에러 메시지도 설정할 수 있다.
  if data['title'] == data['description']:
    raise serializers.ValidationError(
      "Title and Description must be different from one another.")
  return data

input wrong data error return

제목과 설명이 같으면 설정한 에러, 에러 메시지가 출력되지만 내용을 달리 입력하면 아래와 같이 정상 작동하면서 새 인스턴스가 생성된다.

200ok

다음으로, field level validation을 짜보자. 이번에는 “title” 값이 60자를 넘어가면 ValidationError가 발생하게 할 것이다.

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

Object level validation처럼 data를 받아 처리해주는 게 아니라 validate_title로 필드를 지정했다. 필드값을 value 파라미터로 받아 validation 작업을 해준다.

코드를 저장한 뒤 60자 넘는 제목을 작성하면 아래와 같이 설정해준 에러 메시지가 출력된다.

input wrong data error return