5๐
โ
I had had the same issue in my job, to solve this Iโve created the following custom aggregate:
class SumDecimal(Func):
function = 'SUM'
name = 'sum'
contains_aggregate = True
output_field = DecimalField()
template = '%(function)s(%(expressions)s)'
def __init__(self, *args, **kwargs):
self.decimal_places = kwargs.pop('decimal_places', None)
super(SumDecimal, self).__init__(*args, **kwargs)
def as_sql(self, compiler, connection, function=None, template=None):
sql = super(SumDecimal, self).as_sql(
compiler=compiler,
connection=connection,
function=function,
template=template)
if self.decimal_places:
sql, params = sql
sql = 'CAST(%s AS DECIMAL(16, %d))' % (sql, self.decimal_places)
return sql, params
return sql
To use this is pretty simple, just use like:
mymodel.objects.all().annotate(sum_value=SumDecimal('value', decimal_places=2))
Source:stackexchange.com