Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type annotating a recursive serializer #1374

Open
johnthagen opened this issue Feb 3, 2025 · 1 comment · May be fixed by #1377
Open

Type annotating a recursive serializer #1374

johnthagen opened this issue Feb 3, 2025 · 1 comment · May be fixed by #1377

Comments

@johnthagen
Copy link
Contributor

johnthagen commented Feb 3, 2025

I'd like to model the following type:

class ItemSerializer(ModelSerializer):
    children = ItemSerializer(many=True)

Due to Python limitations with how classes are defined this is not possible.

I thought about looking at https://github.com/heywbj/django-rest-framework-recursive, but this hasn't been updated for 5 years and there are reports about it not working with modern Django versions:

Finally, I thought of trying a SerializerMethod like:

class ItemSerializer(ModelSerializer):
    children = SerializerMethodField()

    def get_children(self, instance: Item) -> list[Item]:
        children = instance...
        return ItemSerializer(children, many=True).data

But type hints containing Model subclasses don't seem to be supported, which makes sense.

I was curious if there was some other way to get a nested serializer to be registered/recognized with drf-spectacular.

@johnthagen
Copy link
Contributor Author

johnthagen commented Feb 4, 2025

Interesting, using the Serializer as a type hint seems to work:

from __future__ import annotations

class ItemSerializer(ModelSerializer):
    children = SerializerMethodField()

    def get_children(self, instance: Item) -> ItemSerializer:
        children = instance...
        return ItemSerializer(children, many=True).data

Looks like this is documented here:

It takes either basic types or a Serializer as argument. In case of basic types (e.g. str, int, etc.) a type hint is already sufficient.

It might be more discoverable if the opening page that lists SerializerMethodField (https://drf-spectacular.readthedocs.io/en/latest/readme.html) linked to this subsection.

@johnthagen johnthagen linked a pull request Feb 4, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant