# DRF - Automatic Deep Serialization of OneToOne Field

**URL:** <https://forum.djangoproject.com/t/drf-automatic-deep-serialization-of-onetoone-field/27313>\
**Category:** Forms & APIs\
**Created:** [January 23, 2024, 2:53pm UTC](https://forum.djangoproject.com/t/drf-automatic-deep-serialization-of-onetoone-field/27313 "2024-01-23T14:53:47Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![samul-1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/samul-1/32/4767_2.png) [@samul-1](https://forum.djangoproject.com/u/samul-1)\
**Post date:** [January 23, 2024, 2:53pm UTC](https://forum.djangoproject.com/t/drf-automatic-deep-serialization-of-onetoone-field/27313/1 "2024-01-23T14:53:47Z")

</div>

I came across some behavior that doesn’t quite look right to me, and could possibly be a bug in the way Django REST treats automatic deep serialization.

The [depth argument](https://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization) of the ModelSerializer.Meta class is used to expand relations of the serialized models automatically.

It creates a NestedSerializer on the fly:

```auto
def build_nested_field(self, field_name, relation_info, nested_depth):
        """
        Create nested fields for forward and reverse relationships.
        """
        class NestedSerializer(ModelSerializer):
            class Meta:
                model = relation_info.related_model
                depth = nested_depth - 1
                fields = ' __all__'

        field_class = NestedSerializer
        field_kwargs = get_nested_relation_kwargs(relation_info)

        return field_class, field_kwargs

```

This method is called on each relation field of the model, if the serializer has a `depth` parameter \>0.

```auto
def build_field(self, field_name, info, model_class, nested_depth):
        """
        Return a two tuple of (cls, kwargs) to build a serializer field with.
        """
        if field_name in info.fields_and_pk:
            model_field = info.fields_and_pk[field_name]
            return self.build_standard_field(field_name, model_field)

        elif field_name in info.relations:
            relation_info = info.relations[field_name]
            if not nested_depth:
                return self.build_relational_field(field_name, relation_info)
            else:
                return self.build_nested_field(field_name, relation_info, nested_depth)

        # ...

```

The `info` object is obtained by calling this method:

```auto
def get_field_info(model):
    """
    Given a model class, returns a `FieldInfo` instance, which is a
    `namedtuple`, containing metadata about the various field types on the model
    including information about their relationships.
    """
    opts = model._meta.concrete_model._meta
    

    pk = _get_pk(opts)
    fields = _get_fields(opts)
    forward_relations = _get_forward_relationships(opts)
    reverse_relations = _get_reverse_relationships(opts)
    fields_and_pk = _merge_fields_and_pk(pk, fields)
    relationships = _merge_relationships(forward_relations, reverse_relations)

    return FieldInfo(pk, fields, forward_relations, reverse_relations,
                     fields_and_pk, relationships)

```

and the `_get_forward_relationships` method looks like this:

```auto
def _get_forward_relationships(opts):
    """
    Returns an `OrderedDict` of field names to `RelationInfo`.
    """
    forward_relations = OrderedDict()
    for field in [field for field in opts.fields if field.serialize and field.remote_field]:
        forward_relations[field.name] = RelationInfo(
            model_field=field,
            related_model=field.remote_field.model,
            to_many=False,
            to_field=_get_to_field(field),
            has_through_model=False,
            reverse=False
        )
    # ...

```

Apparently, the issue is that a OneToOne field has its `serialize` parameter set to False. As a result, it’s not included in the `relations` dict and isn’t expanded into a NestedSerializer, but just shown as a pk of the related object.

Is this the expected behavior? Shouldn’t a OneToOne field behave like a ForeignKey, where the related object is serialized using a NestedSerializer?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [January 23, 2024, 3:06pm UTC](https://forum.djangoproject.com/t/drf-automatic-deep-serialization-of-onetoone-field/27313/2 "2024-01-23T15:06:19Z")

</div>

Note: This isn’t an official support channel for the Django Rest Framework.

While there are people here willing to try to help with problems using it, this isn’t the best place to look for authoritative answers regarding design decisions. Any responses you get here are likely going to be conjectures made and conclusions obtained by other users of the framework.

See [Support](https://www.django-rest-framework.org/#support) for the best places to try to get official or authoritative responses.

---

<div class="post-metadata">

**Author:** ![samul-1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/samul-1/32/4767_2.png) [@samul-1](https://forum.djangoproject.com/u/samul-1)\
**Post date:** [January 23, 2024, 3:19pm UTC](https://forum.djangoproject.com/t/drf-automatic-deep-serialization-of-onetoone-field/27313/3 "2024-01-23T15:19:38Z")

</div>

Got you, I posted this on the official mailing list as well. Thanks
