Katsuya Obara
Katsuya Obara

Reputation: 963

Flatten json return by DRF

I have json API returned as below format.
But I want to return json API decomposing namingzone key as specified below.
Could anyone tell me how I can revise serializer to achieve this?
serializer.py is also specified below.
For models.py and views.py, please refer to my previous post.

current

{
    "zone": {
        "zone": "office_enclosed",
        "namingzone": [
            {
                "naming": "moffice"
            }
        ]
    },
    "lpd": 11.9,
    "sensor": true
},
{
    "zone": {
        "zone": "office_open",
        "namingzone": [
            {
                "naming": "off"
            },
            {
                "naming": "office"
            }
        ]
    },
    "lpd": 10.5,
    "sensor": true
}  

Target

{
    "zone": "office_enclosed",
    "naming": "moffice",
    "lpd": 11.9,
    "sensor": true
},
{
    "zone": "office_open",
    "naming": "off",
    "lpd": 10.5,
    "sensor": true
},
{
    "zone": "office_open",
    "naming": "office",
    "lpd": 10.5,
    "sensor": true
}  

serializer.py

class namingNewSerializer(serializers.ModelSerializer):

    class Meta:
        model=Naming
        fields=('naming',)

class zoneSerializer(serializers.ModelSerializer):
    namingzone=namingNewSerializer(many=True)

    class Meta:
        model=Zone
        fields = ('zone','namingzone')

class lightSerializer(serializers.ModelSerializer):
    zone = zoneSerializer()

    class Meta:
        model=Light
        fields = ('zone','lpd','sensor')

class namingSerializer(serializers.ModelSerializer):
    zone=zoneSerializer()

    class Meta:
        model=Naming
        fields=('zone','naming')

Upvotes: 0

Views: 277

Answers (2)

ruddra
ruddra

Reputation: 52018

I would say using Serializer might complicate the implementations. Rather, you can take an pythonic approach. Try like this:

class SomeView(APIView):
     ...
     def get(self, request, *args, **kwargs):
         data = lightSerializer(Light.objects.all(), many=True).data
         data = list(data)  # convert lazy object to list
         updated_data = list()
         for item in data:
             newdict = dict()
             zone = item['zone']
             newdict.update({'zone':zone['zone'], 'lpd': item['lpd'], 'sensor':item['sensor']})
             for naming_zone in zone.get('namingzone'):
                 naming_zone.update(newDict)
                 updated_data.append(naming_zone)

         return Response(updated_data, status=status.HTTP_200_OK)

Upvotes: 1

Jrog
Jrog

Reputation: 1527

See DRF Field document about source. It will help you.

https://www.django-rest-framework.org/api-guide/fields/#source

Upvotes: 0

Related Questions