본문 바로가기

Django/DRF

DRF json으로 null이 올 경우, required 옵션 설정을 통해 대처하는 방법

DRF를 사용하는 웹서버에 json으로 null을 보내면 파이썬은 None으로 인식한다.

DRF나 django에서 CharField와 TextField는 django convention을 따르면 null=Trueblank=True 를 동시에 사용하지 말고, blank=True 만 적용하라고 되어있다.

두 개 다 동시에 사용하면 데이터베이스에 empty string(’’ 혹은 “”)과 null 이라는, 타입이 다른 빈 값이 공존하게 되기 때문이다.

json에 null이 왔을 때는 위의 옵션으로만 대처가 가능하지만 serializer field로 명시되어 있는 attribute가 json에 포함되어 있지 않을 경우, required 옵션을 사용하면 된다.

 

required 옵션은 명시적으로 지정하지 않으명 default는 True다.

 

아래의 예로 확인해보자.

json에 key와 value가 포함되어 있지 않을 때 + required=True

json에 key와 value가 포함되어 있지만 value가 null일 때 + required=True

json에 key와 value가 포함되어 있지만 value가 empty string(json이니까 “”)일 때 + required=True

json에 key와 value가 포함되어 있지 않을 때 + required=False

json에 key와 value가 포함되어 있지만 value가 null일 때 + required=False

json에 key와 value가 포함되어 있지만 value가 empty string(json이니까 “”)일 때 + required=False

drf 코드는 required 빼고는 아래의 6개의 경우에서 코드가 같다.

 

 

  • json에 key와 value가 포함되어 있지 않을 때 + required=True

request로 보낸 json

{
    "name": "test",
    "job": "engineer"
}

drf 코드

from rest_framework import serializers

class UserCreateSerializer(serializers.Serializer):
    name = serializers.CharField(
        help_text="이름",
        max_length=200,
        required=True,
    )
    position = serializers.CharField(
        help_text="지위",
        max_length=200,
        allow_blank=True,
        required=True,    
    )
    job = serializers.CharField(
        help_text="직업",
        max_length=200,
        allow_blank=True,
        required=True,    
    )

# serializing
serializer = UserCreateSerializer(data=request.data)
if serializer.is_valid():
    pass
else:
    return json_resonse(status=400, msg=serializer.errors)

이 때에는 job과 position에 required=True 가 되어 있다면, json에 job과 postion의 key와 value가 포함되어 있지 않으므로 serializer.is_valid() 의 타이밍에서 에러가 발생한다.

 

 

  • json에 key와 value가 포함되어 있지만 value가 null일 때 + required=True
{
    "name": "test",
    "position": null,
    "job": "engineer"
}

위의 json과 같이 null이 전달되고 serializer의 field의 required=True 일 경우,

allow_null=False 이므로(명시적으로 allow_null=True 를 설정하지 않았다.) 시리얼라이저 에러가 발생한다. FE로부터 null 값으로 requst가 오는 경우가 있다면 serializer의 validate_attribute(이 경우에는 validate_position) 메소드에 아래와 같은 코드를 작성해서 대비하면 된다.

def validate_position(self, postion):
    if position is None:
        position = ""
    return position

 

 

  • json에 key와 value가 포함되어 있지만 value가 empty string(json이니까 “”)일 때 + required=True
{
    "name": "test",
    "position": "",
    "job": "engineer"
}

allow_blank=True 이므로 에러가 발생하지 않는다.

 

 

  • json에 key와 value가 포함되어 있지 않을 때 + required=False
{
    "name": "test",
    "job": "engineer"
}

json에서 position이라는 key와 value 자체가 전달되지 않고 required=False 이므로 에러가 발생하지 않는다.

 

 

  • json에 key와 value가 포함되어 있지만 value가 null일 때 + required=False
{
    "name": "test",
    "position": null,
    "job": "engineer"
}

allow_null=False 이므로(명시적으로 allow_null=True 를 설정하지 않았다.) 시리얼라이저 에러가 발생한다. FE로부터 null 값으로 requst가 오는 경우가 있다면 serializer의 validate_attribute(이 경우에는 validate_position) 메소드에 아래와 같은 코드를 작성해서 대비하면 된다.

def validate_position(self, postion):
    if position is None:
        position = ""
    return position

 

 

  • json에 key와 value가 포함되어 있지만 value가 empty string(json이니까 “”)일 때 + required=False
{
    "name": "test",
    "position": "",
    "job": "engineer"
}

allow_blank=True 이므로 에러가 발생하지 않는다.

required 옵션은 request로 json을 받았을 때 serializer의 field에 명시되어 있지만 json에 field명의 key와 value가 없어도 된다면 False, 있어야 한다면 True를 해야한다. null이 전달됬을 시에는 empty string으로 변환해주는 코드를 사용하거나 예외처리를 해주자.

required 옵션은 default로 True지만

Model Serializer사용하고 models.py의 해당 model의 field에 default값을 설정하거나 blank=True 를 사용하고 있거나 null=True 사용하고 있다면 required 옵션의 default는 False로 자동 설정된다.

Reference

Serializer fields - Django REST framework

'Django > DRF' 카테고리의 다른 글

DRF serializer test code - max_length  (0) 2023.05.04
DRF credentials 메소드 사용법  (0) 2023.02.21
DRF token-based vs session based authentication  (0) 2023.01.31