[Django DRF] Serializer를 통한 데이터 검증
Django DRF에는 Serializer
라는 데이터 타입이 있습니다.
크게 봤을때 모델 인스턴스를 JSON으로 직렬화 하는 역할, `JSON 타입`을 받아서 view로 전달하는 역할이 존합니다.
이때 후자의 경우 올바른 데이터를 받았는지 검증해야할 필요가 있습니다.
모델과 연관된 serializer
를 사용한다면 기본적으로 검증을 거치게 됩니다.
DRF를 사용한다면 클라이언트에서 Django api서버로 POST 요청을 보내면 대부분
urls -> view -> model 순서대로 요청이 들어오게 됩니다.
view에서는 serializer
를 통해 역 직렬화를 통해 모델에 데이터를 저장하는데 이때 데이터를 검증하게 됩니다.
class Icecream(models.Model):
name = models.CharField(max_length=50)
price = models.IntegerField(default=0)
class IcecreamSerializer(serializers.ModelSerializer):
class Meta:
model = Icecream
fields = '__all__'
serializers.ModelSerializer
를 사용하면 따로 사용할 필드를 하나씩 정의하지 않고 모델의 필드를 그대로 쓸 수 있습니다.
Meta
에 model
과 fields
를 지정해주면 지정해준 필드의 형식을 그대로 쓰게됩니다.
여기서는 ‘__all__’
을 사용해서 모델의 모든 필드를 사용하고 있습니다.
class IcecreamViewSet(viewsets.ModelViewSet):
queryset = Icecream.objects.all()
serializer_class = IcecreamSerializer
viewset
에서는 위에서 생성한 serializer_class
를 쓰게됩니다.
이렇게 하면 IcecreamViewSet
을 통하는 모든 요청은 IcecreamSerializer
를 거치게 됩니다.
IcecreamViewSet
으로 빈값과 함께 POST 요청을 보내 보겠습니다.
{
"name": [
"This field is required."
]
}
name
필드가 필요하다는 응답을 받습니다. 위에서 우리는 Icecream 모델을 기반으로 한 ModelSerializer
를 생성해 줬기 때문에 Icecream모델의 필드 속성을 그대로 사용하게 됩니다.
price 필드는 default=0
으로 되어있어서 값이 없으면 0으로 입력이 되기 때문에 필요한값은 name입니다.
만약 name 필수값이 아니길 원한다면 모델 필드 속성에 null=True 를 넣어주면 됩니다.
name = models.CharField(max_length=50)
name 필드는 위와 같이 Icecream 모델에서 max_length
가 50으로 제한되어 있습니다.
만약 50글자 이상의 데이터를 보내면 어떻게 될까요?
{
"name": [
"Ensure this field has no more than 50 characters."
]
}
400에러와 함께 어떤 데이터가 부족한지를 리턴해줍니다.
다음과 같이 새로운 필드를 추가하거나 name 필드를 바꾸는것도 가능합니다.
class IcecreamSerializer(serializers.ModelSerializer):
tasty = serializers.CharField() # 새로운 필드 추가 가능
name = serializers.CharField(max_length=50) # 기존 필드 오버라이딩 가능
class Meta:
model = Icecream
fields = '__all__'
여기서 max_length와 같이 자주 쓰이는 arguement
read_only
: 만약 password와 같은 필드가 있다면 사용자에게 POST요청으로 password를 받아서 검증할때는 사용하겠지만 GET요청을 받았을때 password는 사용자에게 보여주면 안됩니다. 이럴때 read_only속성을 사용하면 데이터를 받을때(읽을때)는 password가 필요하지만 serializer로 데이터를 직렬화 해서 사용자에게 줄때는 password를 보여주지 않게 됩니다. 반대로 write_only 속성 또한 존재합니다.
allow_blank(CharField만 가능)
:
name = serializers.CharField(allow_blank=True)
위와 같은 필드가 있을때 {”name” : “”} 과 같이 빈값이 가능해 집니다.
help_text
: 주석을 넣듯 필드에 관한 설명을 넣을 수 있습니다.
아래에서 다양한 필드와 속성값들을 알아볼 수 있습니다.
https://www.django-rest-framework.org/api-guide/fields/
Serializer fields - Django REST framework
www.django-rest-framework.org