Как настроить схему response api с помощью drf-spectacular для Django Rest Framework

У меня возникла проблема настройки схемы API.

Вот мой случай: Мне нужно возвращать список экземпляров в моем сериализаторе с его полями, но также должно быть одно общее поле агрегации, которое накапливает эти экземпляры модели в список.

Вот пример структуры json:

{
  "comments_amount": 2,
  "comments": [
    {
      "id": 0,
      "card_id": 0,
      "user_id": 0,
      "text": "Comment",
      "created_at": "2024-02-24T09:07:43.946Z",
      "updated_at": "2024-02-24T09:07:43.946Z"
    },
     {
      "id": 1,
      "card_id": 0,
      "user_id": 0,
      "text": "Comment",
      "created_at": "2024-03-24T09:07:43.946Z",
      "updated_at": "2024-03-24T09:07:43.946Z"
    }
  ]
}

Вот мой код для сериализатора:

class CommentResponseSerializer(serializers.ModelSerializer):
    parent_id = serializers.IntegerField(help_text=_("ID of parent comment"), min_value=0, required=False)
    card_id = serializers.IntegerField(help_text=_("Product's card ID"), min_value=0)
    user_id = serializers.IntegerField(help_text=_("ID of user who created this comment"), required=True)

    class Meta:
        model = Comment
        exclude = ["user", "parent", "card"]

А вот для просмотра:

@extend_schema(tags=["Product Cards"], summary="API для комментариев карточек продуктов")
class CommentView(APIView):
    @extend_schema(
        description="API для просмотра комментариев. Доступно всем пользователям.",
        parameters=[
            OpenApiParameter(
                name="card_id", description="ID карточки продукта", required=True, type=int, location="path"
            )
        ],
        request=CommentInputSerializer,
        responses=CommentResponseSerializer,
    )
    def get(self, request, *args, **kwargs):
        card_id = kwargs["card_id"]
        comments = Comment.objects.filter(card_id=card_id)
        serializer = CommentResponseSerializer(comments, many=True)

        data = {
            "comments_amount": comments.count(),
            "comments": serializer.data
        }

        return Response(data, status=status.HTTP_200_OK)

Здесь, как вы можете видеть, я создаю dict с полем comments_amount и comments для самих комментариев с помощью CommentResponseSerializer. Как же я могу представить не только поля CommentReponseSerializer, но и поле comments_amount с помощью drf-spectacular. Буду очень благодарен, если кто-нибудь поможет. Я много искал, но не нашел подходящего решения.

После публикации этого вопроса я пришел к довольно простому и очевидному решению. Итак, я создал новый сериализатор:

class CommentResponseWithAmountSerializer(serializers.Serializer):
    comments_amount = serializers.IntegerField(help_text=_("Amount of comments"))
    comments = CommentResponseSerializer(many=True, help_text=_("List of comments"))

    class Meta:
        fields = "__all__"

И обновленный метод представления get:

@extend_schema(
    description="API для просмотра комментариев. Доступно всем пользователям.",
    parameters=[
        OpenApiParameter(
            name="card_id", description="ID карточки продукта", required=True, type=int, location="path"
        )
    ],
    request=CommentInputSerializer,
    responses=CommentResponseWithAmountSerializer,
)
def get(self, request, *args, **kwargs):
    card_id = kwargs["card_id"]
    comments = Comment.objects.filter(card_id=card_id)

    serializer = CommentResponseWithAmountSerializer(
        {
            "comments_amount": comments.count(),
            "comments": CommentResponseSerializer(comments, many=True).data
        }
    )

    return Response(serializer.data, status=status.HTTP_200_OK)
Вернуться на верх