2022.11.30 - [Django] - [DRF - Django Rest Framework] Serializer Field 톺아보기(1)를 이어서 작성.
2.1.5 allow_null
allow_null이 설정이 안 돼있을 경우 값이 입력되지 않는다면 일반적으로 error가 발생한다. True로 설정할 경우 값이 입력되지 않더라도 유효성 검사(직렬화 단계의)를 통과한다. 하지만 model field에서 null 설정이 되어 있지 않다면 error가 발생한다.
2.1.6 source
필드를 채우는 데 사용할 속성의 이름이다. self와 같은 인수만 사용하거나 URLField(source='get_absolute_url') 또는EmailField(source='user.email') 와 같은 속성을 순회하기 위해 점으로 구분된 표기법을 사용할 수 있는 메서드일 수 있다.
점 표기법으로 필드를 직렬화할 때 속성 순회 중에 개체가 없거나 비어 있는 경우 default 값을 제공해야 할 수 있다.
관계형 orm 모델에 엑세스 하는 경우 source 속성을 사용할 때 가능한 n + 1 문제에 주의하세요.
source='*'에는 전체 개체가 필드로 전달 된다. 이는 중첩 표현을 생성하거나 출력 표현을 결정하기 위해 전체 객체에 액세스해야 하는 필드에 유용할 수 있다.
필드 이름이 기본값이다.
이제 코드로 이해를 하자
class ProjectSerializer(serializers.ModelSerializer):
audios = AudioSerializer(read_only=True, many=True)
audio_count = serializers.IntegerField(source='audios.count') # Audio 개체 데이터의 개수가 표시 된다.
...
아래를 보면 count가 표시되는 것을 볼 수 있다.
// response
...
"audios": [
{
"id": 1,
"project": 1,
...
},
{
"id": 2,
"project": 1,
...
},
{
"id": 3,
"project": 1,
...
},
{
"id": 4,
"project": 1,
...
}
],
"audio_count": 4
해당 audio_count의 source를 살펴보면 AudioSerializer의 개체를 이용하여 점 표기법으로 메소드를 활용한 것을 살펴볼 수 있다. 조금 더 살펴보자 부모 클래스인 Field 클래스를 열어보자
# fields.py
class Field:
...
def __init__(self, *, read_only=False, write_only=False,
required=None, default=empty, initial=empty, source=None,
label=None, help_text=None, style=None,
error_messages=None, validators=None, allow_null=False):
...
self.source = source
...
def bind(self, field_name, parent):
"""
Initializes the field name and parent for the field instance.
Called when a field is added to the parent serializer instance.
"""
# In order to enforce a consistent style, we error if a redundant
# 'source' argument has been used. For example:
# my_field = serializer.CharField(source='my_field')
assert self.source != field_name, (
"It is redundant to specify `source='%s'` on field '%s' in "
"serializer '%s', because it is the same as the field name. "
"Remove the `source` keyword argument." %
(field_name, self.__class__.__name__, parent.__class__.__name__)
)
self.field_name = field_name
self.parent = parent
# `self.label` should default to being based on the field name.
if self.label is None:
self.label = field_name.replace('_', ' ').capitalize()
# self.source should default to being the same as the field name.
if self.source is None:
self.source = field_name
# self.source_attrs is a list of attributes that need to be looked up
# when serializing the instance, or populating the validated data.
if self.source == '*':
self.source_attrs = []
else:
self.source_attrs = self.source.split('.')
init에서 self.source를 초기화 하고 bind 함수에서 사용하고 있다. bind 함수를 살펴 보면 source의 기본 값은 field_name인 것을 알 수 있다. 그리고 앞서 말했듯이 와일드카드(*)로 지정할 경우 아래와 같이 속성이 세팅된다.
def get_attribute(instance, attrs):
"""
Similar to Python's built in `getattr(instance, attr)`,
but takes a list of nested attributes, instead of a single attribute.
Also accepts either attribute lookup on objects or dictionary lookups.
"""
for attr in attrs: # source를 와일드 카드로 지정할 경우 순회를 돌지 않기 때문에 instance가 return 된다.
try:
if isinstance(instance, Mapping):
instance = instance[attr]
else:
instance = getattr(instance, attr)
except ObjectDoesNotExist:
return None
if is_simple_callable(instance):
try:
instance = instance()
except (AttributeError, KeyError) as exc:
# If we raised an Attribute or KeyError here it'd get treated
# as an omitted field in `Field.get_attribute()`. Instead we
# raise a ValueError to ensure the exception is not masked.
raise ValueError('Exception raised in callable attribute "{}"; original exception was: {}'.format(attr, exc))
return instance
source를 와일드카드로 했을 때
# serializers.py
class AudioSerializer(serializers.ModelSerializer):
project_ = serializers.CharField(source='*')
...
// response
"audios": [
{
"id": 1,
...
"project_": "테스트 하나(Audio - 1번째 텍스트)",
},
{
"id": 2,
...
"project_": "테스트 하나(Audio - 2번째 텍스트)",
...
},
...
],
2.1.7 validators
들어오는 필드 입력에 적용되어야 하고 유효성 검사 오류를 발생시키거나 단순히 반환하는 유효성 검사기 함수 목록이다. 유효성 검사기 함수는 일반적으로 serializers.ValidationError를 발생시켜야 하지만 Django 코드 베이스 또는 타사 Django 패키지에 정의돈 유효성 검사기와의 호환성을 위해 Django의 내장 기능 ValidationError도 지원된다.
2.1.8 error_messages
오류 메시지를 보여준다.
2.1.9 label
HTML 양식 필드 또는 기타 설명 요소에서 필드 이름으로 사용할 수 있는 짧은 텍스트 문자열이다.
2.1.10 help_text
HTML 양식 필드 또는 기타 설명 요소에서 필드 설명으로 사용할 수 있는 텍스트 문자열이.
2.1.11 initial
HTML 양식 필드의 값을 미리 채우는데 사용한다. 일반 Django Field와 마찬가지로 콜러블을 전달할 수 있다.
import datetime
from rest_framework import serializers
class ExampleSerializer(serializers.Serializer):
day = serializers.DateField(initial=datetime.date.today)
2.1.12 style
렌더러가 필드를 렌더링하는 방법을 제어하는 데 사용할 수 있는 키-값 쌍의 dict다.
두 가지 예는 다음 'input_type'과 'base_template' 같다.
# Use <input type="password"> for the input.
password = serializers.CharField(
style={'input_type': 'password'}
)
# Use a radio input instead of a select input.
color_channel = serializers.ChoiceField(
choices=['red', 'green', 'blue'],
style={'base_template': 'radio.html'}
)
다음에는 다양한 필드를 알아 보겠다.
언제나 피드백은 환영입니다.
참고
1. https://www.django-rest-framework.org/api-guide/fields/#allow_null
'Django' 카테고리의 다른 글
[Pytest] - django-dotenv 와 pytest-dotenv 오류 (0) | 2022.12.19 |
---|---|
[DRF] - Serializers Class 알아보기(1) (0) | 2022.12.14 |
[DRF - Django Rest Framework] Serializer Field 톺아보기(3) (0) | 2022.12.13 |
Django Queryset - Lazy QuerySet 과 올바른 Caching 사용법 (0) | 2022.12.09 |
[DRF - Django Rest Framework] Serializer Field 톺아보기(1) (0) | 2022.11.30 |