Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework - separate serializer class per method in model based API view

Say I have a simple Django REST Framework view that's extending multiple model classes and serves all the methods in one URL endpoint:

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)

Now I need to use different serializers per method, as my get-method will use different fields than my put-method, example 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

Is it possible to use different serializers for each method in my model based API view?

UPDATE:

I know how to use different serializers inside the methods themselves.

But I need to get the Browsable API generated by Swagger (Django module rest_framework_swagger) to retrieve different serializers for each method. I can see that loading the API browser page triggers get_serializer_class, but inside that method, I don't know what method Swagger tries to get the serializer for.

How can I get rest_framework_swagger to retrieve different serializers per method?

like image 228
Wolkenarchitekt Avatar asked Jul 09 '14 08:07

Wolkenarchitekt


1 Answers

I think there are at least two ways to achieve this:

  1. You simply set the serializer that you want in each of your methods. Like this:

    def get(self, request, *args, **kwargs):
        self.serializer_class = UserViewSerializer
        # ...
        return Response(data={'result': "OK"}, status=200) 
    
  2. You override the get_Serializer_class method. Like this:

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

Hope this helps.

like image 177
AdelaN Avatar answered Sep 23 '22 02:09

AdelaN