'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 |
