Django Rest Framework - отдельный класс сериализатора для каждого метода в представлении API на основе модели

Скажем, у меня есть простое представление Django REST Framework, которое расширяет несколько классов моделей и обслуживает все методы в одной конечной точке URL:

class UserAPIView(RetrieveAPIView, DestroyAPIView, BaseObjectAPIView):
    permission_classes = (IsAuthenticated, )
    serializer_class = UserSerializer

    def get_serializer_class(self, *args, **kwargs):
        # return different serializer depending on method??            
        # return UserUpdateSerializer
        return UserViewSerializer

    def get(self, request, *args, **kwargs):
        """
        Retrieve user details
        """
        # ...
        return Response(data={'result': "OK"}, status=200)

    def delete(self, request, pk):
        """
        Delete user
        """
        # ...
        return Response(data={'result': "OK"}, status=200)

    def put(self, request, pk):
        """
        Change user
        """
        # ...        
        return Response(data={'result': "OK"}, status=200)

Теперь мне нужно использовать разные сериализаторы для каждого метода, так как мой метод get будет использовать разные поля, чем мой put-method, пример serializers:

class UserViewSerializer(serializers.ModelSerializer):
    firstname = serializers.Field(source='firstname')
    lastname = serializers.Field(source='lastname')
    username = serializers.Field(source='username')

    class Meta:
        model = User

class UserUpdateSerializer(serializers.ModelSerializer):
    firstname = serializers.Field(source='firstname')
    lastname = serializers.Field(source='lastname')    

    class Meta:
        model = User

Можно ли использовать разные сериализаторы для каждого метода в представлении API на основе модели?

UPDATE:

Я знаю, как использовать разные сериализаторы внутри самих методов.

Но мне нужно получить API-интерфейс Browsable, созданный Swagger (Django module rest_framework_swagger) для извлечения разных сериализаторов для каждого метода. Я вижу, что загрузка страницы браузера API запускает get_serializer_class, но внутри этого метода я не знаю, какой метод Swagger пытается получить для сериализатора.

Как я могу заставить rest_framework_swagger извлекать разные сериализаторы для каждого метода?

Ответ 1

Я думаю, что для этого есть как минимум два способа:

  • Вы просто устанавливаете сериализатор, который вы хотите в каждом из ваших методов. Вот так:

    def get(self, request, *args, **kwargs):
        self.serializer_class = UserViewSerializer
        # ...
        return Response(data={'result': "OK"}, status=200) 
    
  • Вы переопределяете метод get_Serializer_class. Вот так:

    def get_serializer_class(self, *args, **kwargs):
        if self.request.method == 'POST':
            return UserUpdateSerializer
        return UserViewSerializer
    

Надеюсь, что это поможет.

Ответ 2

Я полагаю, вы могли бы использовать yaml docstring для каждого метода для переопределения сериализаторов. Как:

def put(self, request, pk):
    """Change user

    ---
    serializer: .serializers.UserUpdateSerializer
    """
    # ...
    return Response(data={'result': "OK"}, status=200)