DRF ViewSet дополнительное действие (`@action`) serializer_class
Когда я пытаюсь использовать дополнительные действия Django Rest Framework на наборе представлений, я не могу заставить декоратор serializer_class
работать.
class ClientViewSet(ModelViewSet):
queryset = Client.objects.all()
serializer_class = ClientSerializer
def get_queryset(self):
# Do things
def get_serializer_class(self):
# Do things
@action(detail=True, methods=["get"], serializer_class=ClientDetailSerializer)
def get_by_name(self, request, name=None):
"""
Get one Client searching by name.
@param request:
@param name: Client code
@return: Response
"""
queryset = get_object_or_404(Client, name__iexact=name)
serializer = self.get_serializer(queryset)
return Response(serializer.data)
Итак, даже если дополнительное действие якобы переопределяет класс сериализатора ViewSet по умолчанию, я все равно получаю ClientSerializer
вместо ClientDetailSerializer
.
В официальной документации говорится, что...
Декоратор позволяет переопределить любую конфигурацию уровня набора представлений, такую как
permission_classes
,serializer_class
,filter_backends
...:
Мое переопределение get_serializer_class
по умолчанию использует атрибут ViewSet serializer_class
для моих дополнительных действий. Если я правильно понимаю, это в основном то, что GenericAPIView
get_serializer_class
делает под капотом:
def get_serializer_class(self):
"""
(...)
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
return self.serializer_class
Наверное, я упускаю что-то очевидное. Просто не могу понять, что...
Любая помощь будет принята с благодарностью. Заранее спасибо :)
Почему бы не использовать его таким образом? Я предполагаю, что вы делаете что-то не так в get_serializer_class.
@action(detail=True, methods=["get"], serializer_class=ClientDetailSerializer)
def get_by_name(self, request, name=None):
"""
Get one Client searching by name.
@param request:
@param name: Client code
@return: Response
"""
object = get_object_or_404(Client, name__iexact=name)
serializer = ClientDetailSerializer(object)
return Response(serializer.data)
Когда вы переопределяете get_serializer_class
без вызова суперкласса этого класса, суперкласс не запускается.
пользователь this:
def get_serializer_class(self):
if self.action in ["create"]:
return CreateClientSerializer
elif self.action in ["retrieve"]:
return ClientDetailSerializer
return super().get_serializer_class()