Consider this useless serializer:
class MySerializer(serializers.Serializer):
random_number = serializers.SerializerMethodField()
def get_random_number(self):
# Chosen by fair dice roll.
# Guaranteed to be random.
return 4
Assuming you added this serializer in an endpoint and generated the OpenAPI schema, the serializer would look like this:
properties:
random_number:
type: string
required:
- random_number
The issue here is there is no way to tell DRF to use type: number
here. I thought of a few possibilities:
output_field
attribute, like serializers.SerializerMethodField(output_field=serializers.IntegerField())
, similarly to Django's Query Expressionsopenapi_type(serializers.SerializerMethodField(), serializers.IntegerField())
An attribute, similarly to setting descriptions on admin actions:
random_number = serializers.SerializerMethodField()
def get_random_number(self):
return 4
get_random_number.output_field = serializers.IntegerField()
Hi @Lucidiot.
I guess the immediate way to do this would be to override AutoSchema._map_field()
.
You can either do that per-serializer/view to expect the field in question, or add an attribute like you say.
We'll come round to something in this way eventually, but currently I'm not sure about the best option, in terms of API.
For me, I think the API I'd prefer is something using type hinting like:
def get_foo(self, obj) -> int:
return 1
It works in every Python version currently supported. This idea was used in https://github.com/encode/django-rest-framework/pull/7089 but it wasn't separated out into another PR. Looking at that implementation, it seems like it doesn't handle collections. At some point you'd be better using a nested serializer, but I think simple cases like List[int]
, List[str]
, Dict[str, int]
etc. should be supported.
@carlfarrington what do you think? Is it worth trying this approach or are there problems with it? If it's worth trying, is it also worth getting something basic in that can handle basic types and ignore nested fields for now or would we want (nested or not) arrays and objects from the start?
We'll promote and document map_field()
for 3.12. That's the right way to go here.
Most helpful comment
For me, I think the API I'd prefer is something using type hinting like:
It works in every Python version currently supported. This idea was used in https://github.com/encode/django-rest-framework/pull/7089 but it wasn't separated out into another PR. Looking at that implementation, it seems like it doesn't handle collections. At some point you'd be better using a nested serializer, but I think simple cases like
List[int]
,List[str]
,Dict[str, int]
etc. should be supported.@carlfarrington what do you think? Is it worth trying this approach or are there problems with it? If it's worth trying, is it also worth getting something basic in that can handle basic types and ignore nested fields for now or would we want (nested or not) arrays and objects from the start?