Django Rest Framework - How to use url parameters in API requests to exclude fields in response

Let's say I have an API that returns some simple list of objects at the /users endpoint

{
  "count": 42,
  "results": [
      {
        "name": "David",
        "age": 30,
        "location": "Alaska"
      },
      ...
   ]

}

I would like to pass a simple boolean that changes the output by removing a field.

So /users?abridged=True would return the same objects, but omit a field.

{
  "count": 42,
  "results": [
      {
        "name": "David",
        "age": 30,
      },
      ...
   ]

}

I suppose I could create two serializers, one for the full version and one abridged, but I'm not sure how I could use a url parameter to select which serializer to use. Is there a better way to do this?

One way is to override list method and modify fields dynamically based on the presence of the query string param:

views.py

class UserViewSet(viewsets.ModelViewSet):
    User = get_user_model()
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def list(self, request):
        abridged = request.GET.get('abridged', None)
        
        if abridged:
            fields = ('username', 'age',)
        else:
            fields = ('username', 'age', 'location')

        serializer = UserListSerializer(
            {'count': self.get_queryset().count()}, 
            context={'fields': fields, 'qs': self.get_queryset()}
        )
        return Response(serializer.data)

Note that I used a "wrapper" serializer for the list method in order to obtain the desired output. Using extra context to pass data for its SerializerMethodField.

serializers.py

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    ...

class UserSerializer(DynamicFieldsModelSerializer):
    class Meta:
        model = get_user_model()
        fields = ['username', 'age', 'location']

class UserListSerializer(serializers.Serializer):
    count = serializers.IntegerField()
    results = serializers.SerializerMethodField()

    def get_results(self, obj):
        serializer = UserSerializer(self.context['qs'], many=True, fields=self.context['fields'])
        return serializer.data
Back to Top