Serializer는 Data를 직렬화 하여 json 형태로 변환하는 작업이다. 보통 Serializer를 사용하기 위해서는 아래와 같이 serializer 내의 클래스를 상속하여 클래스를 선언한다.
class SomeSerializer(serializers.ModelSerializer)
Serializer를 선언한 이후에 안에서 Field를 선언할 수 있는데 그 종류마다 사용 용도가 다르다.
해당 필드는 Serializer 선언 시 Meta 안에 연결할 Model에 없는 Column(속성)을 만들 수 있다. 예를 들어 User Model에 account_number라는 속성이 없을 때 아래와 같이 선언하면 된다.
선언 후 account_number라는 변수를 정의하기 위해서는 "get언더바명수명" 으로 함수를 선언하고 그 안에서 변수를 정의하면 된다.
class UserSerializer(serializers.ModelSerializer):
account_number = serializers.SerializerMethodField()
class Meta:
model = User
fields = '__all__'
def get_account(self, object):
account = object.account
return account.account_number
여기서 object는 Serializer에 인자로 들어간 instance를 뜻한다. 위 예시에서는 아래와 같은 Serializer가 사용되었다. 즉 object는 user인 것이다.
user = User.objects.get(id=1)
UserSerializer(instance=user)
해당 필드는 모델과 연결된 다른 모델의 속성을 가져오거나, 현재 모델의 속성을 다른 이름으로 할 때 사용한다.
class DepositValidationSerializer(serializers.ModelSerializer):
transfer_identifier = serializers.ReadOnlyField(source="id")
class Meta:
model = TransferIdentifier
fields = [
'transfer_identifier',
'account_number',
'user_name',
'transfer_amount'
]
extra_kwargs = {
"user_name": {"write_only": True},
"account_number": {"write_only": True},
"transfer_amount": {"write_only": True},
}
예를 들어 transfer_identifer가 TransferIdentifier 모델에 속성으로 없을 경우, 모델 내의 id 값을 transfer_identifer으로 변경하여 사용할 수 있다.
위와 같이 사용할 경우 통신 시 응답으로 아래 처럼 전달 된다. 즉 key는 transfer_identifier지만 value는 실제로는 TransferIdentifier의 id 값인 것이다.
{"transfer_identifier": 1}
위와 같은 경우는 POST 통신에서 body에 데이터를 아래와 같이 전달했다.
POST body
{
"account_number": 123123,
"user_name": "test1",
"transfer_amount": 100
}
Serializer validate
def validate(self, data):
def validate_psword(self, value):
만약 여기서 전달되는 key값에 대하여 field가 없다면 validate 함수의 data와 value에 아무런 값도 들어가지 않는다. 그러므로 Field를 꼭 선언해주어야 한다.
여기서 Field를 선언하는 방법은 두 가지이다.
POST body
{
"transfer_identifier": 1,
"signature": "asdbasd123"
}
Serializer
class DepositSerialzer(serializers.ModelSerializer):
transfer_identifier = serializers.CharField(max_length=50, write_only=True)
signature = serializers.CharField(max_length=150, write_only=True)
class Meta:
model = TransferIdentifier
fields = [
'transfer_identifier',
'signature',
'status'
]
위와 같이 POST 요청에 body 데이터를 보낸다고 해보자. TranferIdentifier 모델 안에는 transfer_identifier와 signature 속성이 없다. 이런 상황에서는 바로 fields에 transfer_identifier와 signature를 추가할 수 없다. 위와 같이 transfer_identifier = serializers.CharField() 를 선언해주면 fields의 추가가 가능하며, body 데이터를 받을 수 있게 된다.
참고로 write_only=True를 선언할 경우 응답으로 해당 속성을 보내지 않으므로 필요할 때 유용하게 사용된다.