Django Rest Framework - Как использовать параметры url в запросах API для исключения полей в ответе

Допустим, у меня есть API, который возвращает некоторый простой список объектов в конечной точке /users

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

}

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

Так что /users?abridged=True вернет те же объекты, но без поля.

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

}

Полагаю, я могу создать два сериализатора, один для полной версии, другой для сокращенной, но я не уверен, как я могу использовать параметр url для выбора сериализатора. Есть ли лучший способ сделать это?

Один из способов - переопределить метод list и изменять поля динамически на основе наличия параметра строки запроса:

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)

Обратите внимание, что я использовал сериализатор "wrapper" для метода list, чтобы получить желаемый результат. Используя экстра контекст для передачи данных для своего 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
Вернуться на верх