'Django Rest Objects being showed twice or more

Currently I have a model named Board, and a Board can be colored and shapped:

class Board(models.Model):
    name = models.CharField(max_length=200)
    colored = models.BooleanField(default=False)
    shaped = models.BooleanField(default=False)

I would like to create an API that return all colored and all shapped separated in a single request like this:

[{
        "all_colored": [
            {
                "id": 1,
                "name": "test 1",
                "colored": true,
                "shaped": false
            }
        ],
        "all_shaped": [
            {
                "id": 2,
                "name": "test 2",
                "colored": false,
                "shaped": true
            }
        ]
    }]

Yeah, I need the exactly output above, no matter how I can achieve this. But currently I'm receiving this twice or more, if I create 2 Boards, I will receive twice, if i create 3 boards I'll receive three times, the current output when create 2 boards:

[
    {
        "all_colored": [
            {
                "id": 1,
                "name": "test 1",
                "colored": true,
                "shaped": false
            }
        ],
        "all_shaped": [
            {
                "id": 2,
                "name": "test 2",
                "colored": false,
                "shaped": true
            }
        ]
    },
    {
        "all_colored": [
            {
                "id": 1,
                "name": "test 1",
                "colored": true,
                "shaped": false
            }
        ],
        "all_shaped": [
            {
                "id": 2,
                "name": "test 2",
                "colored": false,
                "shaped": true
            }
        ]
    }
]

My viewset:

class BoardViewSet(ModelViewSet):
    serializer_class = BoardSerializer
    queryset = Board.objects.all()

    def get_serializer_class(self):
        if self.action == "list":
            return ListFilterSerializer

        return self.serializer_class

my serializers:

class BoardSerializer(serializers.ModelSerializer):
    class Meta:
        model = Board
        fields = "__all__"


class ListFilterSerializer(serializers.ModelSerializer):
    all_colored = serializers.SerializerMethodField()
    all_shaped = serializers.SerializerMethodField()

    def get_all_colored(self, obj):
        qs = Board.objects.filter(colored=True)
        data = BoardSerializer(qs, many=True).data
        return data

    def get_all_shaped(self, obj):
        qs = Board.objects.filter(shaped=True)
        data = BoardSerializer(qs, many=True).data
        return data

    class Meta:
        model = Board
        fields = ["all_colored", "all_shaped"]

I have not found any doc that helped me, if you have a link about how to implement this, please give me.



Solution 1:[1]

By default ModelViewSet.list applies serializer to all objects in the queryset. In your case it calls get_all_colored and get_all_shaped for every Board object. To change this behavior you can override list method in the BoardViewSet class:

def list(self, request, *args, **kwargs):
    serializer = ListFilterSerializer()
    return Response(serializer.data)

You may find default implementation in the ListModelMixin class

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 awesoon