django-rest-frameworkのserializerでいろんなメソッドの呼ばれる順番

# この記事の目的
* django-rest-framework を使っていて、serializerが中でどういう処理をしているのかがわからなくてつらい
* そうだ、フレームワークの中身を読んでみよう

# 環境
* djangorestframework: 3.9.1

# 見るところ
* rest_framework/serializers.py
    * `class Serializer(BaseSerializer)`の辺り
    * とりあえずここ理解すれば他もなんとかなる？


# 読む
* renderersとかmixinsとかは後回しでいきなりserializers

## to_internal_value(self, data)

```python
 471     def to_internal_value(self, data):
 472         """
 473         Dict of native values <- Dict of primitive datatypes.
 474         """
 475         if not isinstance(data, Mapping):
 476             message = self.error_messages['invalid'].format(
 477                 datatype=type(data).__name__
 478             )
 479             raise ValidationError({
 480                 api_settings.NON_FIELD_ERRORS_KEY: [message]
 481             }, code='invalid')
```
* 受け取ったデータ型の検証とか?


```python

 483         ret = OrderedDict()
 484         errors = OrderedDict()
 485         fields = self._writable_fields
```
* `ret`: 最終的な返却値
* `errors`: 例外情報
* `fields`: `to_internal_value`で処理する対象が格納されている。
    * `_writable_fields`は以下の通り。

```python
 367     @cached_property
 368     def _writable_fields(self):
 369         return [
 370             field for field in self.fields.values() if not field.read_only
 371         ]
```
* `read_only`プロパティが`False`になっているfieldだけが含まれるらしい。

```python
 487         for field in fields:
 488             validate_method = getattr(self, 'validate_' + field.field_name, None)
 489             primitive_value = field.get_value(data)
 490             try:
 491                 validated_value = field.run_validation(primitive_value)
```
* fieldの`run_vaildation`を実行

```python
 523     def run_validation(self, data=empty):
 524         """
 525         Validate a simple representation and return the internal value.
 526
 527         The provided data may be `empty` if no representation was included
 528         in the input.
 529
 530         May raise `SkipField` if the field should not be included in the
 531         validated data.
 532         """
 533         (is_empty_value, data) = self.validate_empty_values(data)
 534         if is_empty_value:
 535             return data
 536         value = self.to_internal_value(data)
 537         self.run_validators(value)
 538         return value
```
* 渡ってきた値の`to_internal_value`を呼び出し。
    * ここの処理はまた今度読む

```python
 492                 if validate_method is not None:
 493                     validated_value = validate_method(validated_value)
```
* `validate_<field名>` という名前でメソッドが宣言されてたらそれを実行する

```python
 494             except ValidationError as exc:
 495                 errors[field.field_name] = exc.detail
 496             except DjangoValidationError as exc:
 497                 errors[field.field_name] = get_error_detail(exc)
 498             except SkipField:
 499                 pass
```
* 例外が発生したらerrorsに入れる

```python
 500             else:
 501                 set_value(ret, field.source_attrs, validated_value)
```
* validate_<field名>のメソッドを実行した結果を`ret`に入れる

```python
 503         if errors:
 504             raise ValidationError(errors)
```
* 何かしらのエラーがあったら例外発火

```python
 506         return ret
```
## to_representation

```python
 508     def to_representation(self, instance):
 509         """
 510         Object instance -> Dict of primitive datatypes.
 511         """
 512         ret = OrderedDict()
 513         fields = self._readable_fields
```
* `fields`: `_readable_fields`で取得
    * `_readable_fields`は以下の処理
    * `write_only`でないフィールドを取得している

```python
 373     @cached_property
 374     def _readable_fields(self):
 375         return [
 376             field for field in self.fields.values()
 377             if not field.write_only
 378         ]
```

```python
 514
 515         for field in fields:
 516             try:
 517                 attribute = field.get_attribute(instance)
 518             except SkipField:
 519                 continue
```
* `instance`から指定のフィールドに格納されているデータを取得

```python
 521             # We skip `to_representation` for `None` values so that fields do
 522             # not have to explicitly deal with that case.
 523             #
 524             # For related fields with `use_pk_only_optimization` we need to
 525             # resolve the pk value.
 526             check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute
 527             if check_for_none is None:
 528                 ret[field.field_name] = None
 529             else:
 530                 ret[field.field_name] = field.to_representation(attribute)
```
* コメントのとおり…
* `to_internal_value`と同様に、fieldの`to_representation`も順に呼び出される

```python
 531
 532         return ret
```

# まとめ
* to_internal_value
    * 各fieldに対して`to_internal_value`とvalidationを繰り返してる
    * オブジェクトがネストされているときは、深いところから`to_internal_value`と`validate_<field名>` が実行されることになりそう
* to_representation
    * 各`field`の`to_representation`を呼び出してるくらい？
* `field.to_internal_value`とか`field.to_representation`はまた今度読む