serializerMethodField()가 뭐일까

권수민·2023년 10월 19일
0

일단 공식문서에서 이를 어케 설명하는지 봐보려한다.

serializerMethodField는 Miscellaneous fields 속에 속해져있다. 기타 항복..필드라는 그런 개념인데, readonlyfield나 hiddenfield등 같은 개념이 속해있다.

읽으면서 약간 헷갈린 개념이 속성
(attribute)과 필드(Field)의 개념이었다.

알고있는데 내가 이해한 개념과는 살짝 다르다고해야하나. 범위가 넓다해야하나. 그래서 다시 명확히 정리해두려한다.

Django에서의 속성 (Attribute),모델 속성 (Model Attribute),필드 (Field)의 개념::

즉, 속성이란:
Python객체에서 어떤 값을 표현하는 상수나 변수를 의미한다.
예를들어, apple이란 변수가 fruit이라는 모델에 들어가있으면
모델이 가지는 변수나 함수 => 모델의 속성이라고 할수있고,
모델이 결국 클래스타입으로 정의되기 때문에 => 클래스 속성이라고도 할 수 있겠다.

그럼 모델속성은 무엇인가?

장고에서 데이터베이스의 테이블과 연결되는 클래스 => 모델, 그리고
위에서 언급했다시피 모델클라스 내에 정의된 변수나 함수를 의미한다.

그렇다면 필드란?

위의 모델 속성 중 데이터베이스의 컬럼(테이블컬럼)에 직접연결되는 속성을 => Field필드라 칭한다.

이 컬럼을 나타내는 변수, 즉 필드를 CharField, IntegerField, ForeignKey의 타입클래스를 통해 변수를 정의한다.

예) models.CharField or serializers.CharField

여기서 헷갈렸던 부분은 ?

=> 바로 속성 = 필드라고 생각했던 부분이다.
속성의 개념의 넓이는 넓기 때문에 @property로 정의된 메소드 또한 python의 속성으로 속성으로 취급되지만 필드는 아닌것.
모델의 '필드'는 데이터베이스의 컬럼을 나타내는 반면, '속성'은 모델의 변수나 함수를 일반적으로 의미 즉, 데이터베이스에는 저장이되지않으면 필드가 아닌것이다.

ReadOnlyField
A field class that simply returns the value of the field without modification.

This field is used by default with ModelSerializer when including field names that relate to an attribute rather than a model field.

Signature: ReadOnlyField()

For example, if has_expired was a property on the Account model, then the following serializer would automatically generate it as a ReadOnlyField:

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'has_expired'] 

이렇게 설명되어진 부분에서
This field is used by default with ModelSerializer when including field names that relate to an attribute rather than a model field. => 이부분이 헷갈렸는데

즉, has_expired 같은 속성이 Account 모델의 필드가 아니라 (즉, 데이터베이스의 컬럼이 아니라) 그냥 Python의 속성 (예를 들면, @property로 정의된 메서드)인 경우, DRF의 ModelSerializer는 이를 ReadOnlyField로 자동으로 처리한다는것이다.

여기서 @property데코레이터를 사용하여 메서드 정의시 -> 속성처럼 호출할수있다, 허나 데이터베이스애는 저장이되지않음.

그렇다면 여기서 SerializerMethodField는??

SerializerMethodField는 Django Rest Framework (DRF)의 시리얼라이저 내에서 사용되는 특별한 필드 유형으로서, 이 필드를 사용하면 시리얼라이저 내에서 특정 메서드의 반환 값을 필드 값으로 사용할 수 있다.

즉, 모델 필드가 아닌 사용자 정의 로직을 기반한 값을 시리얼라이저의 출력에 포함 시킬수 있다.

사용방법은?

시리얼라이저 내에서 SerializerMethodField를 정의하고, 해당 필드와 관련된 메서드를 시리얼라이저 내에 구현합니다. 이 메서드의 이름은 get_<field_name> 형식을 따라야한다.

예시:

from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
full_name = serializers.SerializerMethodField()

class Meta:
    model = User
    fields = ('id', 'username', 'full_name')

def get_full_name(self, obj):
    return f"{obj.first_name} {obj.last_name}"
    
    

위의 예시에서 full_name 필드는 SerializerMethodField로 정의되어있다. 따라서 get_full_name 메서드를 시리얼라이저 내에서 정의하였고, 이 메서드는 User 모델의 first_name과 last_name을 조합하여 전체 이름을 반환하게 커스터마이징을 해주었다.

이와 같이 SerializerMethodField는 표준 모델 필드나 시리얼라이저 필드가 아닌, 사용자 정의 로직을 사용하여 값을 반환할 때 유용하게 사용한다.

다른예시


class ArticleListSerializer(serializers.ModelSerializer):
    
    user = serializers.SerializerMethodField()
    def get_user(self, obj):
        # obj는 현재 직렬화되고 있는 Article 객체의 인스턴스
        # (serializer = ArticleListSerializer(instance=articles,many=True))
        # 즉, obj는 이 articles 쿼리셋 내의 개별 Article 인스턴스를 나타냄
        #obj 해당 아티클. 
        return obj.user.email
    class Meta:
        model = Article
        fields = ('pk','title','image','updated_at','user') 
profile
초보개발자

1개의 댓글

comment-user-thumbnail
2023년 10월 19일

평소 헷갈리던 개념을 다시 정리하며 명확하게 이해하게 되었군요~ 정확히 짚고 넘어가는 모습 좋습니다.👍

답글 달기