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()
не может сопоставить действие с методами.