I’m trying to get specific fields from my database using the object.values()
attribute, as such:
stocks = Stock.objects.values("ticker", "stock", "exchange__exchange_code", "earnings_yield", "roic")
The reason I’m not using Stock.objects.filter()...
is because I only need a subset of the fields, and as far as I know, values()
is the way to go.
stocks[0]
returns this:
{
'ticker': 'ATRLJ-B',
'stock': 'Atrium Ljungberg AB (publ)',
'exchange__exchange_code': 'ST',
'earnings_yield': Decimal('0.0250'), 'roic': Decimal('0.0200')
}
How do I get earnings_yield
and roic
as regular floats? E.g, proper JSON formatted
I tried
clean = json.dumps(list(stocks), cls=DjangoJSONEncoder)
stocks = json.loads(clean)
But that returns the decimals as strings, not decimals
Answer
I think you can do it with ExpressionWrapper
, use FloatField
as output field and store it to another field name.
from django.db.models import FloatField, F, ExpressionWrapper
Stock.objects.annotate(
earnings_yield_float=ExpressionWrapper(
F('earnings_yield'),
output_field=FloatField()
),
roic_float=ExpressionWrapper(
F('roic'),
output_field=FloatField()
)
).values(
'ticker',
'stock',
'exchange__exchange_code',
'earnings_yield_float',
'roic_float'
)
But, bassed on your case, I’ll recomend you to use https://www.django-rest-framework.org instead. By using this, your Stock data will be converted as JSON format when you call
serializer.data
(like below example):
For example in your serializers.py
from rest_framework import serializers
from yourapp.models import Stock
class StockSerializer(serializers.ModelSerializer):
class Meta:
model = Stock
fields = ('ticker', 'stock', 'exchange__exchange_code',
'earnings_yield', 'roic')
Then in your views.py
:
from rest_framework import generics
from rest_framework.response import Response
from yourapp.models import Stock
class StockView(generics.ListAPIView):
queryset = Stock.objects.all()
def get_queryset(self):
return self.queryset.filter(...)
def list(self, request):
queryset = self.get_queryset()
serializer = StockSerializer(queryset, many=True)
return Response(serializer.data)
Meanwhile, StockSerializer(queryset, many=True).data
will return OrderDict
, but for a single object it will return as JSON output.
The other way, if you want to dealing with exact JSON output at all, you can use default rest_framework.renderers.JSONRenderer
.
from rest_framework.renderers import JSONRenderer
from yourapp.serializers import StockSerializer
from yourapp.models import Stock
queryset = Stock.objects.all()
serializer = StockSerializer(queryset, many=True)
data = JSONRenderer().render(serializer.data) # b'[{"id":1, "ticker": ...}]
# the to proces that data you can use the json module
import json
json.loads(data) # [{'id': 1, 'ticker': ...}]