2

It seems SerializerMethodField assumes the data type of the field is a string, even if it is an int. For instance, I have this field:

num_sections = serializers.SerializerMethodField(help_text="The number of sections for this course")

def get_num_sections(self, obj) -> int:
    return obj.sections.count()

However, in the auto-generated OpenAPI schema, this field shows up as a string field. Is there any way to set the proper data type for a SerializerMethodField?

3 Answers 3

3

you can use this snippet:

from drf_spectacular.utils import extend_schema_field

num_sections = serializers.SerializerMethodField(help_text="The number of sections for this course")

@extend_schema_field(serializers.IntegerField)
def get_num_sections(self, obj) -> int:
    return obj.sections.count()
Sign up to request clarification or add additional context in comments.

1 Comment

I think you don't need both the return type hint and the extend_schema_field decorator. They do the same thing.
1

It is a bit of a heavy-handed solution, but this works for me:

num_sections = type('SerializerMethodField', (serializers.SerializerMethodField, serializers.IntegerField), dict())(
        help_text="The number of sections for this course")

def get_num_sections(self, obj) -> int:
    return obj.sections.count()

The 3 argument type function can be used as a shorthand for making a child of two classes.

Please let me know if anyone has any better solutions or comments on this.

2 Comments

It is work with drf-yasg.
drf-yasg is deprecated, better to use drf_spectacular with extend_schema_field decorator.
0

You can also create serializer for your return value and use it like type hint for your method.

class BranchType(serializers.Serializer):
    id = serializers.IntegerField()
    is_main = serializers.BooleanField()

    class Meta:
        fields = ['id', 'is_main']

class Company(serializers.ModelSerializer):
    branch = serializers.SerializerMethodField(method_name='get_branch')

    def get_branch(self, obj) -> BranchType:
        branch = obj.branches.first()
        if not branch:
            raise serializers.ValidationError(_('There is no branch for this company!'))
        return branch.id, branch.is_main

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.