I finally found two solutions that worked for me:
Thanks to @Ramy's answer, I overidden the DjangoJSONEncoder
, to support the conversion of a Decimal to a float:
import decimal
import uuid
from django.utils.functional import Promise
from django.core.serializers.json import DjangoJSONEncoder
class JsonDecimalToFloatEncoder(DjangoJSONEncoder):
def default(self, o):
if isinstance(o, (decimal.Decimal, uuid.UUID, Promise)):
return float(o)
return super().default(o)
and I used it as he mentioned:
monthly_revenue = list(Booking.objects.annotate(month=Month('created_at'))
.values('month')
.annotate(total=Sum('price'))
.order_by('month'))
json_result = json.dumps(monthly_revenue,cls=ExtendedEncoder)
json_result
'[{"month": 11, "total": 4550.0}]'
this solution requires more work on the server side, so i opted for the second solution of @rossi which does more work on the database rather than the server, and that's what the django's documentation suggest.
from django.db.models import FloatField
from django.db.models.functions import Cast
list(Booking.objects.annotate(month=Month('created_at'))
.values('month')
.annotate(total_as_f=Cast('total',
output_field=FloatField()))
.order_by('month'))
[{'month': 11, 'total': Decimal('4550.00'), 'total_as_f': 4550.0}]
hope this will help anyone in the futur.