drf-extra-fields icon indicating copy to clipboard operation
drf-extra-fields copied to clipboard

PresentablePrimaryKeyRelatedField creates issue in redoc documentation.

Open techlearner96 opened this issue 2 years ago • 2 comments

I have a serializer field which works differently for read and write. I used PresentablePrimaryKeyRelatedField for that. e.g: car_type = PresentablePrimaryKeyRelatedField( queryset=CarType.objects.all(), presentation_serializer=CarTypeSerializer, read_source=None ) This works well when accessing the api, like in request i give an integer value to car_type field and in response it gives a dictionary to car_type field. Api request-response thing worked well. Issue is with swagger documentation. In documentation, it gives car_type as integer field in both request and response schema. How can i deal with that?

techlearner96 avatar Jun 17 '22 13:06 techlearner96

AFAIK, there is no solution for this right now. It needs to be improved.

If you are using drf-spectacular, PolymorphicProxySerializer may help. It allows you to show different serializers depending on the situation. You may define an input and output serializer and represent them differently.

Something like that:

# input/accept
car_type = PrimaryKeyRelatedField(
    queryset=CarType.objects.all(),
)

# output/response
car_type = CarTypeSerializer()

https://drf-spectacular.readthedocs.io/en/latest/drf_spectacular.html#drf_spectacular.utils.PolymorphicProxySerializer https://drf-spectacular.readthedocs.io/en/latest/drf_spectacular.html?highlight=PolymorphicProxySerializer#drf_spectacular.utils.PolymorphicProxySerializer

gokselcoban avatar Jun 27 '22 15:06 gokselcoban

You can use OpenApiSerializerFieldExtension

from drf_extra_fields.relations import PresentablePrimaryKeyRelatedField
from drf_spectacular.extensions import OpenApiSerializerFieldExtension
from drf_spectacular.settings import spectacular_settings

class PresentablePrimaryKeyRelatedFieldSchemaExtension(OpenApiSerializerFieldExtension):
    target_class = PresentablePrimaryKeyRelatedField

    def map_serializer_field(self, auto_schema, direction):
        if direction == "response" and spectacular_settings.COMPONENT_SPLIT_REQUEST:
            return auto_schema._map_serializer_field(
                self.target.presentation_serializer, direction, bypass_extensions=True
            )
        else:
            return auto_schema._map_serializer_field(
                self.target, direction, bypass_extensions=True
            )

ckarli avatar Oct 25 '22 13:10 ckarli