Considere este serializador inútil:
class MySerializer(serializers.Serializer):
random_number = serializers.SerializerMethodField()
def get_random_number(self):
# Chosen by fair dice roll.
# Guaranteed to be random.
return 4
Supondo que você adicionou este serializador em um endpoint e gerou o esquema OpenAPI, o serializador ficaria assim:
properties:
random_number:
type: string
required:
- random_number
O problema aqui é que não há como dizer ao DRF para usar type: number
aqui. Pensei em algumas possibilidades:
output_field
, como serializers.SerializerMethodField(output_field=serializers.IntegerField())
, semelhante às expressões de consulta do Djangoopenapi_type(serializers.SerializerMethodField(), serializers.IntegerField())
Um atributo, semelhante às descrições de configuração nas ações do administrador :
random_number = serializers.SerializerMethodField()
def get_random_number(self):
return 4
get_random_number.output_field = serializers.IntegerField()
Olá, @Lucidiot.
Acho que a maneira imediata de fazer isso seria sobrescrever AutoSchema._map_field()
.
Você pode fazer isso por serializador / visualização para esperar o campo em questão ou adicionar um atributo como você disse.
Nós vamos chegar a algo desta forma eventualmente, mas atualmente não tenho certeza sobre a melhor opção, em termos de API.
Para mim, acho que a API que eu prefiro é algo que use dicas de tipo como:
def get_foo(self, obj) -> int:
return 1
Ele funciona em todas as versões do Python atualmente suportadas. Essa ideia foi usada em https://github.com/encode/django-rest-framework/pull/7089, mas não foi separada em outro PR. Olhando para essa implementação, parece que ela não lida com coleções. Em algum ponto, seria melhor usar um serializador aninhado, mas acho que casos simples como List[int]
, List[str]
, Dict[str, int]
etc. devem ser suportados.
@carlfarrington o que você acha? Vale a pena tentar essa abordagem ou há problemas com ela? Se vale a pena tentar, também vale a pena obter algo básico que possa manipular tipos básicos e ignorar campos aninhados por enquanto ou desejaríamos (aninhados ou não) matrizes e objetos desde o início?
Vamos promover e documentar map_field()
por 3.12. Essa é a maneira certa de ir aqui.
Comentários muito úteis
Para mim, acho que a API que eu prefiro é algo que use dicas de tipo como:
Ele funciona em todas as versões do Python atualmente suportadas. Essa ideia foi usada em https://github.com/encode/django-rest-framework/pull/7089, mas não foi separada em outro PR. Olhando para essa implementação, parece que ela não lida com coleções. Em algum ponto, seria melhor usar um serializador aninhado, mas acho que casos simples como
List[int]
,List[str]
,Dict[str, int]
etc. devem ser suportados.@carlfarrington o que você acha? Vale a pena tentar essa abordagem ou há problemas com ela? Se vale a pena tentar, também vale a pena obter algo básico que possa manipular tipos básicos e ignorar campos aninhados por enquanto ou desejaríamos (aninhados ou não) matrizes e objetos desde o início?