Django REST Framework - Пользовательское действие для использования другого класса сериализатора, пустой результат

Я пытаюсь определить пользовательское действие, которое будет использовать другой класс сериализатора, но я получаю пустой результат от этого действия, и я не уверен почему. Я основывал свой код определения действия на документации DRF, но, возможно, я что-то упускаю, поскольку для меня это что-то новое.

У меня есть простой пример на основе Authors & Books, чтобы продемонстрировать это.

Вот мой код набора представлений и действие, в котором, как мне кажется, кроется решение:

class AuthorViewSet(viewsets.ModelViewSet):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['first_name', 'last_name']

    @action(detail=False, serializer_class=AuthorNoBookListSerializer)
    def no_booklist(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

У меня есть два сериализатора: Один со списком книг каждого автора, а другой без:

class AuthorSerializer(serializers.ModelSerializer):
    book_list = serializers.ListField(source='books')

    class Meta:
        model = Author
        fields = ('id', 'first_name', 'last_name', 'book_list')

class AuthorNoBookListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ('id', 'first_name', 'last_name')

Если я поменяю serializer_class = AuthorSerializer на serializer_class = AuthorNoBookListSerializer в наборе представлений, я увижу, что оба сериализатора работают нормально:

Использование AuthorSerializer:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 4,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "first_name": "Ken",
            "last_name": "Kesey",
            "book_list": [
                "One Flew Over the Cuckoo's Nest"
            ]
        },
        {
            "id": 2,
            "first_name": "Brian",
            "last_name": "Kernighan",
            "book_list": [
                "The C Programming Language"
            ]
        },
        {
            "id": 3,
            "first_name": "Dennis",
            "last_name": "Ritchie",
            "book_list": [
                "The C Programming Language",
                "Lions' Commentary on UNIX: 6th Edition with Source Code"
            ]
        },
        {
            "id": 4,
            "first_name": "John",
            "last_name": "Lions",
            "book_list": [
                "Lions' Commentary on UNIX: 6th Edition with Source Code"
            ]
        }
    ]
}

With AuthorNoBookListSerializer:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 4,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "first_name": "Ken",
            "last_name": "Kesey"
        },
        {
            "id": 2,
            "first_name": "Brian",
            "last_name": "Kernighan"
        },
        {
            "id": 3,
            "first_name": "Dennis",
            "last_name": "Ritchie"
        },
        {
            "id": 4,
            "first_name": "John",
            "last_name": "Lions"
        }
    ]
}

Но используя действие (в http://localhost:8000/api/authors/no_booklist/) я получаю пустой ответ:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{}

Я думаю, что мое определение действия как-то неправильно. Я не уверен, правильно ли я создаю Response. Любое понимание будет оценено по достоинству.

Как вы сказали, проблема не в классе сериализатора. Ваша проблема кроется здесь @action(detail=False, serializer_class=AuthorNoBookListSerializer)

Декоратору действия нужен methods kwarg и ваша проблема будет решена.

@action(methods = ["get"], detail=False, serializer_class=AuthorNoBookListSerializer)

Иначе метод as_view() не может сопоставить действие с методами.

Вернуться на верх