'Submitting SUMMARY Data from Django to React using DRF

I'm starting to test some API data between django and React using Rest API. I'm able to submit this data between Djnago model and React front end.

[
    {
        "id": 1,
        "gender": "Male",
        "age": 40,
        "updated": "2022-04-25T18:55:23.304456Z",
        "created": "2022-04-25T14:07:48.282139Z"
    },
    {
        "id": 2,
        "gender": "Male",
        "age": 33,
        "updated": "2022-04-25T18:55:23.304456Z",
        "created": "2022-04-25T14:07:48.282139Z"
    },
    {
        "id": 3,
        "gender": "Female",
        "age": 22,
        "updated": "2022-04-25T18:55:23.304456Z",
        "created": "2022-04-25T14:07:48.282139Z"
    },
    {
        "id": 4,
        "gender": "Female",
        "age": 33,
        "updated": "2022-04-25T18:55:23.304456Z",
        "created": "2022-04-25T14:07:48.282139Z"
    },
]

My goal is not to submit this raw data, but instead to submit summary data (data analysis) that calculates the average age for males and females, so I should be getting something like this:

[
        {
            "gender": "Male",
            "average_age": 36.5,
        },
        {
            "gender": "Male",
            "average_age": 27.5,
        }
]

in TestDrf.js

import React from "react"
import axios from 'axios'


export default function App() {

    const [incomingData, setIncomingData] = React.useState([])

    React.useEffect(function() {
        console.log('effect ran')
        axios.get('http://127.0.0.1:8000/test/')
            .then(data => setIncomingData(data))
    }, [])
    
    return (
        <div>
            <pre>{JSON.stringify(incomingData.data, null, 2)}</pre>
        </div>
    )
}

in views.py

from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import Test
from .serializers import TestSerializer

@api_view(['GET'])
def getData(request):
    test_data= Test.objects.all()
    result = Test.objects.values('gender')
                           .annotate(average_age=Avg('age'))
    serializer = TestSerializer(test_data, many=True)
    return Response(serializer.data)

Where should I be making these cross tabulations? on the backend or front end? if on the backend should I be creating new models for the summary data?

I tried looking online for advice on this but I was unlucky!



Solution 1:[1]

A Django query can be used in the backend to perform aggregation; new model is not needed for summary data.

An SQL query for getting average age by gender from a 'person' table would be something like this.

SELECT gender, AVG(age) AS average_age
FROM person
GROUP BY gender;

The equivalent Django query would be similar to this.

from django.db.models import Avg

result = Person.objects.values('gender')
                       .annotate(average_age=Avg('age'))

UPDATE: Adding a class based API view

class GetData(APIView):
        
    def get(self):
        
        result = Test.objects.values('gender').annotate(average_age=Avg('age'))
        
        response_data = {}
        response_data['data'] = list(result)
        
        return Response(response_data, status=status.HTTP_200_OK)

urls.py should be updated to use this API view.

path('getdata/', GetData.as_view()),

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