Skip to content

[Feature request] Use typing.Annotated to redefine field types #92

@MaksimZayats

Description

@MaksimZayats

Hi, thanks for the amazing project :)

I'm having function like this to create serializers inline:

# python3.12.0
from __future__ import annotations

from typing import Any, cast, get_type_hints

from rest_framework import serializers
from rest_framework_dataclasses.serializers import DataclassSerializer


def as_serializer[DataClass: Any](
    dataclass_type: DataClass,
    **kwargs: Any,
) -> type[DataclassSerializer[DataClass]]:
    """Create a serializer from a dataclass.

    This is a helper function to make it easier to create serializers from dataclasses.
    It is equivalent to:
    ```
    class MySerializer(DataclassSerializer):
        class Meta:
            dataclass = MyDataclass
    ```
    """
    field_overrides: dict[str, serializers.Field] = {}

    type_hints = get_type_hints(dataclass_type, include_extras=True)
    for field_name, field_type in type_hints.items():
        metadata = getattr(field_type, "__metadata__", None)
        if not metadata:
            continue

        for value in metadata:
            if not isinstance(value, serializers.Field):
                continue

            field_overrides[field_name] = value
            break

    return cast(
        type[DataclassSerializer[DataClass]],
        type(
            f"{dataclass_type.__name__}Serializer",
            (DataclassSerializer,),
            {
                "Meta": type("Meta", (), {"dataclass": dataclass_type}),
                **field_overrides,
                **kwargs,
            },
        ),
    )

So now I can create serializers from dataclasses that looks like this:

@dataclass
class UploadDocumentRequest:
    file: Annotated[
        InMemoryUploadedFile,
        serializers.FileField(),
    ]


serializer_class = as_serializer(UploadDocumentRequest)

Without checking for Annotated types, I got this error:

NotImplementedError: Automatic serializer field deduction not supported for field 'file' on 'UploadDocumentRequest' of type '<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>' (during search for field of type '<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>').

I was wondering if it's possible to implement discovery of fields from Annotated[...] on your side.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions