shyam yadav
shyam yadav

Reputation: 275

Django rest API: How I can serialize data properly

I am new to django rest framework. I am getting the response data for not in the format I need. Any help will be appreciated. Below is my code.

model.py

class Price(models.Model):
    ticker = models.CharField(max_length=15, null=False, blank=False) 
    price_date=models.DateField(null=False, blank=False)
    daily_pe = models.FloatField(blank=True, null=True)
    
    class Meta:
        db_table= 'price'
        unique_together = ('ticker', 'price_date')

    def __str__(self):
        return "%s %s %s " % (self.ticker, self.price_date, daily_pe)

serializers.py

class ChartSerilizer(serializers.ModelSerializer):
    class Meta:
        model = Price
        fields = ['ticker', 'daily_pe']

view.py

class peChartViewSet(APIView):
    def get(self, request):
        queryset = Price.objects.all()
        serializer = ChartSerilizer(queryset, many=True)
        return JsonResponse(serializer.data, safe=False)

This is how am getting the response:

[
    {
        "ticker": "AAPL",
        "daily_pe": 25.144920802584345
    },
    {
        "ticker": "AAPL",
        "daily_pe": 25.043920960028977
    },
    {
        "ticker": "WMT",
        "daily_pe": 24.930801136366966
    },
    {
        "ticker": "WMT",
        "daily_pe": 25.504480242081453
    },
]

But I need the response like this :

[
    {
         "Ticker": "AAPL",
         "daily_pe": [25.144920802584345, 25.043920960028977]
    },
    {
         "Ticker": "WMT",
         "daily_pe": [24.930801136366966,25.504480242081453]
    }
]

Upvotes: 0

Views: 102

Answers (2)

Amrez
Amrez

Reputation: 629

you can do the thing you wanted by using ArrayAgg aggregation function

views.py

from django.contrib.postgres.aggregates import ArrayAgg

class peChartViewSet(APIView):
    def get(self, request):
        queryset = Price.objects.values('ticker').annotate(
            daily_pe_list=ArrayAgg('daily_pe')
        )
        serializer = ChartSerilizer(queryset, many=True)
        return JsonResponse(serializer.data, safe=False)

and also change daily_pe's type to ListField
serializers.py

class ChartSerilizer(serializers.ModelSerializer):
    Ticker = serializers.CharField(source='ticker')
    daily_pe = serializers.ListField(source='daily_pe_list')

    class Meta:
        model = Price
        fields = ['Ticker', 'daily_pe']

based on your answer, you want result list in order of price_date, so for this purpose, you can add ordering argument to ArrayAgg like this:

queryset = Price.objects.values('ticker').annotate(
    daily_pe_list=ArrayAgg('daily_pe', ordering='price_date')
)

* sorry I answered late, i wasn't around my pc.

Upvotes: 1

shyam yadav
shyam yadav

Reputation: 275

There must me a better way, but I got desired result (almost). Here is my updated view.py

class peChartViewSet(APIView):
def get(self, request):
    tickers = ['AAPL', 'WMT']
    data=[]
    
    for tick in tickers:
        print(tick)
        # tick = request.query_params["ticker"]    
        queryset = Price.objects.all().filter(ticker=tick).order_by('price_date')
        serializer = ChartSerilizer(queryset, many=True)
        data.append({tick : serializer.data})
      
    return Response(data)

Upvotes: 1

Related Questions