Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Sum() in Django returns number with 13 decimal places when evaluating numbers with only 2 decimal places?

I am learning Django and creating a cart application. What I am trying to do here is to display on the HTML page the sum of all the cart items 'prices'.

Now, I know this is probably the worst way to do it, as I have seen many tutorials, but I'd rather learn step by step.

So what I am doing here is setting the variable 'total' equal to the sum of all prices using the Sum() function documented here.

The problem is that it displays a number with 13 decimal places, although my model allows just 2 decimal places. How can I overcome this issue?

Here is all the code, and obviously If you have any tip about a better 'basic' way to do this (a best practice) please let me know in the comments.

'models.py'

from django.db import models
from django.contrib.auth.models import User


# Create your models here.
class Item(models.Model):
    name = models.CharField(max_length=25)
    price = models.DecimalField(max_digits=5, decimal_places=2)

    def __str__(self):
        return self.name


class Cart(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    items = models.ManyToManyField(Item)

    def __str__(self):
        return 'Order number: %s' % self.id

'views.py'

from django.shortcuts import render
from .models import Cart, Item
from django.db.models import Sum


# Create your views here.
def home(request):
    items = Item.objects.all()
    carts = Cart.objects.all()
    length = len(Cart.objects.all())
    cart = carts[length - 1]
    cart_items = cart.items.all()
    total = cart_items.aggregate(Sum('price'))['price__sum']
    return render(request, 'cart/home.html', {'cart': cart,
                                              'items': items,
                                              'cart_items': cart_items,
                                              'total': total})

and my 'home.html'

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home page</title>
</head>
<body>
<div><h1>Menu</h1></div>
{% for item in items %}
<ul>{{ item }} £{{ item.price}} <button>Add</button></ul>
{% endfor %}
<div><h1>Order</h1></div>
{{ cart }}
{% for item in cart_items %}
    <ul>{{ item.name }} {{ item.price }}</ul>
{% endfor %}
<h2>Total</h2>
{{ total }}
</body>
</html>
like image 703
Techoplite Avatar asked Sep 05 '25 03:09

Techoplite


1 Answers

If you're using SQLite, you should know that it doesn't support decimal internally, as explained here. That's why Sum() returns a float.

You should therefore either use python float formatting functions to round total to 2 decimals or you can use the floatformat template filter.

like image 194
dirkgroten Avatar answered Sep 07 '25 22:09

dirkgroten



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!