[Django]-Django-rest-framework return created object but with fewer fields

5👍

✅

Well I see multiple possibilites here:
First (my favorite), is send request object to serializer, then serializer will dynamically select your wanted fields:

def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data,context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Then inside serializer:

class SnippetSerializer(serializers.IDontKnow):
    class Meta:
        model = YourModel
        fields = ('url', 'field1','field2','field3')
        write_only_fields = ()
    def __init__(self, *args, **kwargs):
        super(SnippetSerializer, self).__init__(*args, **kwargs)
        if self.context != {}:
            request = self.context['request']
            if request.method == 'POST':
                self.write_only_fields = {'field1':self.fields['field1'], 'field3':self.fields['field3']}

This should make field1 and field3 only writeable, so they won’t be returned.

Second, maybe easier solution is to define other serializer, unique for the post method:

def post(self, request, format=None):
    serializer = PostSnippetSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

you can specify which field you dont wont to be retuned:

 class PostSnippetSerializer(serializers.IDontKnow):
        class Meta:
            model = YourModel
            fields = ('url', 'field1','field2','field3')
            write_only_fields = ('field1','field3')

field1 and field 3 wont be returned in response,

Third way, is to directly create your response in your view:

def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            results = {'url': serializer.data['url'],'field2':serializer.data['field2']}
            return Response(results, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

This will return only url and field2, so field1 and field3 will be saved but not returned.

2👍

For anyone else having the same question, this is what Tom Christie has said:

Either:

  • Consider using write_only=True on the fields you don’t want as output.
  • Use a different serializer for returning the response to the one you use for validation.
  • Just return the response data directly, without using a serializer.

Leave a comment