Abdul
Abdul

Reputation: 186

facing challenges in creating JSON response for API using DRF python

I have created a API which fetches the data from the database and gives me this output JSON in the below format

{
    "curriculum": 
    [
            {
                "id": "1",
                "grade_level": "ES",
                "subject": "ELA",
                "subject_abbr": "ELA",
                "product_id": 446,                
                "series_title": "",
            },
            {
                "id": "2",
                "grade_level": "ES",
                "subject": "ELA",
                "subject_abbr": "ELA",
                "product_id": 446,
                "series_title": "",
            },
            {
                "id": "3",
                "grade_level": "ES",
                "subject": "Math",
                "subject_abbr": "Math",
                "product_id": 235,
                "series_title": "",
            },
            {
                "id": "4",
                "grade_level": "ES",
                "subject": "Math",
                "subject_abbr": "Math",
                "product_id": 235,                
                "series_title": "",
            }
    ]
}

But I need my output to be in this below format.

{
    "curriculum": 
    {
        "ES ELA": [
            {
                "id": "1",
                "grade_level": "ES",
                "subject": "ELA",
                "subject_abbr": "ELA",
                "product_id": 446,                
                "series_title": ""
            },
            {
                "id": "2",
                "grade_level": "ES",
                "subject": "ELA",
                "subject_abbr": "ELA",
                "product_id": 446,
                "series_title": ""
            }],
        "ES Math": [    
            {
                "id": "3",
                "grade_level": "ES",
                "subject": "Math",
                "subject_abbr": "Math",
                "product_id": 235,
                "series_title": ""
            },
            {
                "id": "4",
                "grade_level": "ES",
                "subject": "Math",
                "subject_abbr": "Math",
                "product_id": 235,                
                "series_title": ""
            }
        ]   
    }
}

And please find serializer below

class DetailSerializer(ModelSerializer):
    people = serializers.SerializerMethodField()
    curriculum = serializers.SerializerMethodField()
    finance = serializers.SerializerMethodField()

    class Meta:
        model = table_main
        fields = '__all__'

    def get_people(self, obj):
        queryset_list = peopletable.objects.all()
        c = queryset_list.filter(id=obj.id)
        serializer = ContactSerializer(c, many=True)
        return serializer.data

    def get_curriculum(self, obj):
        queryset_list = curriculumtable.objects.all()
        c = queryset_list.filter(id=obj.id)
        serializer = CurriculumSerializer(c, many=True)
        return serializer.data

    def get_finance(self, obj):
        queryset_list = finances.objects.all()
        c = queryset_list.filter(id=obj.id).order_by('year').reverse()[:1]
        serializer = FundingsSerializer(c, many=True)
        return serializer.data

In the expected output "ES ELA" and "ES Math" are nothing but grade_level and subject_abbr values. I tried using nested serializers as well but it didnt work. please help me how can I do this.

Upvotes: 0

Views: 36

Answers (1)

Brian Destura
Brian Destura

Reputation: 12068

You can do this in get_curriculum:

    def get_curriculum(self, obj):
        ...
        curriculum_map = {}
        for c in serializer.data:
            key = f"{c['grade_level']} {c['subject_abbr']}"
            if key in curriculum_map:
                curriculum_map[key].append(c)
            else:
                curriculum_map[key] = [c, ]
        return curriculum_map

Or override to_representation:

class DetailSerializer(ModelSerializer):
    ...
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        curriculum_map = {}
        for c in representation['curriculum']:
            key = f"{c['grade_level']} {c['subject_abbr']}"
            if key in curriculum_map:
                curriculum_map[key].append(c)
            else:
                curriculum_map[key] = [c, ]
        representation['curriculum'] = curriculum_map
        return representation

Upvotes: 1

Related Questions