Django Rest Framework - единый серайлайзер для API и drf-spectacular
У меня есть сериализатор для DRF и drf-spectacular. Мой сериализатор работает так, как я ожидаю, но в GUI он представлен неправильно. Поэтому мне нужно иметь два разных сериализатора один для схемы, а второй для конечной точки. Но я хочу использовать один, как это исправить?
Мой сериализатор:
class GetConversionCasesSerializer(serializers.Serializer):
conversionId = serializers.SerializerMethodField()
cases = serializers.SerializerMethodField()
def get_cases(self, obj):
serializer = ResultDataSerializer(ResultData.objects.filter(conversion=obj), many=True)
data = serializer.data
return data
def get_conversionId(self, obj):
return obj.id
Сериализатор схем:
class GetConversionCasesSerializerSchema(serializers.Serializer):
conversionId = serializers.IntegerField()
cases = serializers.ListSerializer(child=ResultDataSerializer())
Api конечная точка:
@extend_schema(request=None, responses=GetConversionCasesSerializerSchema())
def get(self, *args, **kwargs):
if self.request.version == "v1":
conversion_id = self.kwargs.get('conversion_id')
instance = Conversion.objects.get(id=conversion_id)
serializer = GetConversionCasesSerializer(instance)
return Response(serializer.data)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
Когда я использую для отображения схемы обычный селиализатор, я имею:
в сериализаторе схем:
Как исправить первый сериализатор и иметь один для схемы и метода get?
Поскольку ваши модели связаны, вы можете просто вложить сериализаторы. Вот простой пример:
from rest_framework import serializers
from app.models import Conversion, ResultData
class ResultDataSerializer(serializers.ModelSerializer):
# TODO: Define only the attributes you're interested
class Meta:
model = ResultData
fields = '__all__'
class GetConversionCasesSerializer(serializers.ModelSerializer):
conversionId = serializers.CharField(source='id')
cases = ResultDataSerializer(many=True, source='resultdata_set') # `source` depends on your case
class Meta:
model = Conversion
fields = ('id', 'resultdata_set',) # add other fields of interest
Обратите внимание, что я везде использовал ModelSerializer
, поскольку он уже реализует некоторую логику для создания ресурсов (не интересную в вашем случае, если он только возвращает данные вызывающей стороне) и автоматически сопоставляет поля модели с полями DRF.