본문 바로가기
Django/Django REST framework

9-2 Serializers-2

by hyun-am 2021. 7. 15.

ModelSerializer

종종 Django 모델 정의와 밀접하게 매핑되는 serializer 클래스를 원할 것입니다.

ModelSerializer 클래스는 모델 필드에 해당하는 필드가 있는 Serializer 클래스를 자동으로 만들 수 있는 shortcut을 제공합니다.

ModelSerializer 클래스는 다음을 제외하고 일반 Serializer 클래스와 동일합니다.

  • 모델에 따라 자동으로 필드셋을 생성합니다.
  • unique_together 벨리데이터와 같은 serializer에 대한 벨리데이터를 자동으로 생성합니다.
  • 여기에는 .create() 및 .update()의 간단한 기본 구현이 포함됩니다.

ModelSerializer는 다음과 같이 생성할 수 있습니다.

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

기본적으로 클래스의 모든 모델 필드는 해당 serializer 필드에 매핑됩니다.

모델의 외래 키와 같은 모든 관계는 PrimaryKeyRelatedField에 매핑됩니다. serializer 관계문서에 명시적으로 포함되지 않는 한 역방향 관계는 기본적으로 포함되지 않습니다.

Inspecting a ModelSerializer

Serializer클래스는 필드 상태를 완전히 검사 할 수 있는 유용한 verbose 표현 문자열을 생성합니다.

이는 자동으로 생성되는 필드 및 벨리데이터를 확인하려는 ModelSerializers로 작업 할 때 특히 유용합니다.

그렇게 하려면 python manage.py shell을 사용하여 Django shell을 연다음 serializer 클래스를 가져 와서 인스턴스화 하고 개체 표현을 프린트합니다.

예시는 다음과 같습니다.

>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print(repr(serializer))
AccountSerializer():
    id = IntegerField(label='ID', read_only=True)
    name = CharField(allow_blank=True, max_length=100, required=False)
    owner = PrimaryKeyRelatedField(queryset=User.objects.all())

Specifying which fields to include

model serializer에서 기본 필드의 하위 집합만 사용하려면 ModelForm에서와 마찬가지로 필드 또는 제외 옵션을 사용하면 됩니다. fields 속성을 사용하여 직렬화해야하는 모든 필드를 명시적으로 설정하는 것이 좋습니다. 이렇게 하면 모델이 변경 될 때 의도하지 않게 데이터가 노출될 가능성이 줄어듭니다.

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

필드 속성을 특수 값 '__all__'로 설정하여 모델의 모든 필드를 사용해야 함을 나타낼 수도 있습니다.

예시는 다음과 같습니다.

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = '__all__'

serializer에서 제외 할 필드 목록에 exclude 속성을 설정할 수 있습니다. 예를들면 다음과 같습니다.

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        exclude = ['users']

위의 예시에서 Account 모델에 account_name, users 및 created 필드가 3개 있는 경우 account_name 필드가 생성되고 직렬화됩니다.

필드 및 excluide 속성의 이름은 일반적으로 모델 클래스의 모델 필드에 매핑됩니다.

버전 3.3.0부터는 속성 필드 중 하나를 제공하거나 제외해야합니다.

Specifying nested serialization

기본 ModelSerializer는 관계에 기본 키를 사용하지만 depth옵션을 사용하면 중첩 된 표현을 쉽게 생성할 수도 있습니다.

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'users', 'created']
        depth = 1

depth옵션은 플랫표현으로 되돌리기 전에 횡단해야하는 관계의 깊이를 나타내는 정수 값으로 설정해야합니다.

직렬화가 수행되는 방식을 사용자 커스터마이징하려면 필드를 직접 정의해야합니다.

Specifying fields explicitly

ModelSerializer에 추가 필드를 추가하거나 Serializer 클래스와 마찬가지로 클래스에서 필드를 선언하여 기본 필드를 재정의 할 수 있습니다.

class AccountSerializer(serializers.ModelSerializer):
    url = serializers.CharField(source='get_absolute_url', read_only=True)
    groups = serializers.PrimaryKeyRelatedField(many=True)

    class Meta:
        model = Account

추가적인 필드는 모델의 모든 속성 또는 호출 가능항목에 해당합니다.

 

Specifying read only fields

여러 필드를 읽기 전용으로 지정할 수 있습니다. read_only = True 속성을 사용하여 명시적으로 각 필드를 추가하는 대신 shortcut 메타 옵션인 read_only_fields를 사용할 수 있습니다.

이 옵션은 필드 이름의 list 또는 튜플이어야하며 다음과 같이 선언됩니다.

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

editable=False가 설정된 모델 필드와 AutoField 필드는 기본적으로 읽기 전용으로 설정되며 read_only_fields 옵션에 추가할 필요가 없습니다.

참고 : 읽기 전용 필드가 모델 수준에서 unique_together 제약 조건의 일부인 특수한 경우가 있습니다. 이 경우 필드는 제약 조건의 유효성을 검사하기 위해 serializer 클래스에 필요하지만 사용자가 편집할 수 없어야합니다.

이를 처리하는 올바른 방법은 read_only=True 및 default = ... 키워드 아규먼트를 모두 제공하여 serializer에 명시적으로 필드를 지정하는 것입니다.

이에대한 한 가지 예는 다른 식별자와 함께 고유한 현재 인증된 사용자에 대한 읽기 전용 관계입니다. 이 경우 다음과 같이 사용자 필드를 선언합니다.

 

user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())

Additional keyword arguments

extra_kwargs 옵션을 사용하여 필드에 임의의 추가 키워드 인수를 지정할 수 있는 Shortcut도 있습니다.

read_only_fields의 경우와 마찬가지로 serializer에서 필드를 명시적으로 선언할 필요가 없음을 의미합니다.

class CreateUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['email', 'username', 'password']
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User(
            email=validated_data['email'],
            username=validated_data['username']
        )
        user.set_password(validated_data['password'])
        user.save()
        return user

필드가 이미 serializer 클래스에서 명시적으로 선언된 경우 extra_kwargs옵션이 무시됩니다.

Relational fields

모델 인스턴스를 직렬화 할 때 관계를 표시하기 위해 선택할 수 있는 여러가지 방법이 있습니다. ModelSerializer의 기본 표현은 관련 인스턴스의 기본 키를 사용하는 것입니다.

대체 표현에는 하이퍼링크를 사용한 직렬화, 완전한 중첩 표현 직렬화 또는 사용자 지정 표현을 사용한 직렬화가 포함됩니다.

Customizing field mappings

ModelSerializer 클래스는 serializer를 인스턴스화 할 때 serializer 필드가 자동으로 결정되는 방식을 변경하기 위해 재정의 할 수 있는 API도 제공합니다.

일반적으로 ModelSerializer가 기본적으로 필요한 필드를 생성하지 않는 경우 클래스에 명시적으로 추가하거나 대신 일반 Serializer클래스를 사용해야합니다. 그러나 어떤 경우에는 주어진 모델에 대해 serializer필드를 만드는 방법을 정의하는 새 기본 클래스를 만들 수 있습니다.

 

.serializer_field_mapping

Django 모델 필드를 drf serializer 필드에 매핑합니다. 이 매핑을 재정의하여 각 모델 필드에 사용해야하는 기본 serializer 필드를 변경할 수 있습니다.

 

.serializer_related_field

이 속성은 기본적으로 관계형 필드에 사용되는 serializer 필드 클래스 여야합니다.

ModelSerializer의 경우 기본값은 PrimaryKeyRelatedField입니다.

HyperlinkedModelSerializer의 경우 기본값은 serializers.HyperlinkedRelatedField입니다.

 

serializer_url_field

serializer의 url필드에 사용해야하는 serializer필드 클래스입니다.

기본값은 serializers.HyperlinkedIdentityField입니다.

 

The field_class and field_kwargs API

serializer에 자동으로 포함되어야하는 각 필드의 클래스 및 키워드 아규먼트를 결정하기 위해 다음 메서드가 호출됩니다. 이러한 각 메서드는 (field_class, field_kwargs)의 두 튜플을 반환해야합니다.

 

.build_standard_field(self, field_name, model_field)

표준 모델 필드에 매핑되는 serializer 필드를 생성하기 위해 호출됩니다.

기본 구현은 serializer_field_mapping 속성을 기반으로 하는 serializer 클래스를 반환합니다.

 

.build_relational_field(self, field_name, relation_info)

표준 모델 필드에 매핑되는 serializer 필드를 생성하기 위해 호출됩니다.

기본 구현은 serializer_field_mapping 속성을 기반으로 하는 serializer 클래스를 반환합니다.

reation_info 아규먼트는 model_field, related_model, to_many 및 has_through_model 속성을 포함하는 명명 된 튜플입니다.

 

.build_nested_field(self, field_name, relation_info, nested_depth)

depth 옵션이 설정된 경우 관계형 모델 필드에 매핑되는 serializer 필드를 생성하기 위해 호출됩니다.

기본 구현은 ModelSerializer 또는 HyperlinkedModelSerializer를 기반으로 중첩 된 serializer 클래스를 동적으로 만듭니다.

nested_depth는 depth 옵션의 값에서 1을 뺀 값입니다.

relation_info 아규먼트는 model_field, related_model 속성을 포함하는 명명 된 튜플입니다.

 

.build_property_field(self, field_name, model_class)

모델 클래스의 속성 또는 아규먼트가 없는 메서드에 매핑되는 serializer 필드를 생성하기 위해 호출됩니다.

기본 구현은 ReadOnlyField 클래스를 반환합니다.

 

.build_url_field(self, field_name, model_class)

serializer의 자체 url필드에 대한 serializer 필드를 생성하기 위해 호출됩니다. 기본 구현은 HyperlinkedIdentityField클래스를 반환합니다.

 

.build_unknown_field(self, field_name, model_class)

필드 이름이 모델 필드 또는 모델 속성에 매핑되지 않은 경우 호출됩니다. 기본 구현에서는 오류가 발생하지만 하위 클래스에서 이 동작을 사용자 지정할 수 있습니다.

 

참고 링크 : https://www.django-rest-framework.org/api-guide/serializers/

 

Serializers - Django REST framework

 

www.django-rest-framework.org

 

'Django > Django REST framework' 카테고리의 다른 글

10. Serializer fields  (0) 2021.07.16
9-3 Serializer-3  (0) 2021.07.15
9-1. Serializers  (0) 2021.07.15
8. Renderers  (0) 2021.07.07
7. Parsers  (0) 2021.06.29

댓글