Django Sum聚合:分转欧元时的精度错误问题求助
The root of your problem is integer division happening at the database level. When you use F('fees')/100, both operands are integers (your fees field is stored as an integer, and 100 is an integer literal), so the database truncates the result to an integer before converting it to a float. That’s why 120 cents becomes 1 instead of 1.2.
To fix this, you need to force floating-point division instead of integer division. Here are two straightforward ways to do it:
Solution 1: Use a float literal with Value()
By passing 100.0 as a float value using Django’s Value class, you ensure the division is performed in floating-point:
from django.db.models import F, FloatField, Sum, Value from payment.models import Payment paymentlist = Payment.objects.all() result = paymentlist.annotate( fees_in_cents=Sum(F('fees'), output_field=FloatField()) ).annotate( fees_in_euro=Sum(F('fees') / Value(100.0), output_field=FloatField()) ) print(result[0].fees_in_cents, result[0].fees_in_euro) # Output: 120.0 1.2
Solution 2: Cast the integer field to float first
You can explicitly convert the fees integer to a float using Cast before dividing by 100:
from django.db.models import F, FloatField, Sum, Cast from payment.models import Payment paymentlist = Payment.objects.all() result = paymentlist.annotate( fees_in_cents=Sum(F('fees'), output_field=FloatField()) ).annotate( fees_in_euro=Sum(Cast(F('fees'), FloatField()) / 100, output_field=FloatField()) ) print(result[0].fees_in_cents, result[0].fees_in_euro) # Output: 120.0 1.2
Bonus: Formatting for display
If you want to show the value as 1.20 (two decimal places) instead of 1.2, format it in Python when displaying:
print("{:.2f}".format(result[0].fees_in_euro)) # Output: 1.20
内容的提问来源于stack exchange,提问作者ChrisRob

