Рассмотрим этот бесполезный сериализатор:
class MySerializer(serializers.Serializer):
random_number = serializers.SerializerMethodField()
def get_random_number(self):
# Chosen by fair dice roll.
# Guaranteed to be random.
return 4
Предполагая, что вы добавили этот сериализатор в конечную точку и сгенерировали схему OpenAPI, сериализатор будет выглядеть следующим образом:
properties:
random_number:
type: string
required:
- random_number
Проблема здесь в том, что нет способа указать DRF использовать здесь type: number
. Я подумал о нескольких возможностях:
output_field
, например serializers.SerializerMethodField(output_field=serializers.IntegerField())
, аналогично выражениям запросов Django.openapi_type(serializers.SerializerMethodField(), serializers.IntegerField())
Атрибут, аналогично настройке описаний действий администратора :
random_number = serializers.SerializerMethodField()
def get_random_number(self):
return 4
get_random_number.output_field = serializers.IntegerField()
Привет @Lucidiot.
Я предполагаю, что непосредственный способ сделать это - переопределить AutoSchema._map_field()
.
Вы можете либо сделать это для каждого сериализатора / представления, чтобы ожидать рассматриваемого поля, либо добавить атрибут, как вы говорите.
В конце концов мы придем к чему-то в этом направлении, но в настоящее время я не уверен в лучшем варианте с точки зрения API.
Для меня я думаю, что API, который я бы предпочел, - это что-то, использующее подсказки типа, например:
def get_foo(self, obj) -> int:
return 1
Он работает во всех поддерживаемых в настоящее время версиях Python. Эта идея использовалась в https://github.com/encode/django-rest-framework/pull/7089, но не была выделена в другой PR. Глядя на эту реализацию, кажется, что она не обрабатывает коллекции. В какой-то момент вам лучше использовать вложенный сериализатор, но я думаю, что должны поддерживаться простые случаи, такие как List[int]
, List[str]
, Dict[str, int]
и т. Д.
@carlfarrington, что ты думаешь? Стоит ли пробовать такой подход или с ним есть проблемы? Если стоит попробовать, стоит ли получить что-то базовое, что может обрабатывать базовые типы и игнорировать вложенные поля на данный момент, или нам нужны (вложенные или нет) массивы и объекты с самого начала?
Мы продвигаем и документируем map_field()
за 3.12. Это правильный путь.
Самый полезный комментарий
Для меня я думаю, что API, который я бы предпочел, - это что-то, использующее подсказки типа, например:
Он работает во всех поддерживаемых в настоящее время версиях Python. Эта идея использовалась в https://github.com/encode/django-rest-framework/pull/7089, но не была выделена в другой PR. Глядя на эту реализацию, кажется, что она не обрабатывает коллекции. В какой-то момент вам лучше использовать вложенный сериализатор, но я думаю, что должны поддерживаться простые случаи, такие как
List[int]
,List[str]
,Dict[str, int]
и т. Д.@carlfarrington, что ты думаешь? Стоит ли пробовать такой подход или с ним есть проблемы? Если стоит попробовать, стоит ли получить что-то базовое, что может обрабатывать базовые типы и игнорировать вложенные поля на данный момент, или нам нужны (вложенные или нет) массивы и объекты с самого начала?