在注释中我做了一些计算,我希望输出为小数,最多8位,最大2位小数。我不知道为什么但是Django会忽略decimal_places和max_digits。 这是我的代码:
Order.objects.all().annotate(
amount=Coalesce(
Sum(
Case(
When(
Q(payments__status='complete'),
then=F('payments__amount') - (
F('payments__amount') * F('payments__vat')/100
)
), output_field=DecimalField(decimal_places=2, max_digits=8)
)
), 0)
).values('amount')
输出= 12.5999999999999996447286321199499070644378662109375
我正在使用Django 1.9.5
答案 0 :(得分:3)
我在工作中遇到了同样的问题,为了解决这个问题,我创建了以下自定义聚合:
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
要使用它非常简单,只需使用像这样:
mymodel.objects.all().annotate(sum_value=SumDecimal('value', decimal_places=2))