Математика в Django ORM и SQLite: десятичная дробь игнорируется, если число круглое, правильный результат, если не круглое
В сложном запросе у меня есть аннотация, подобная этой:
result.annotate(test=ExpressionWrapper(485.00 / F( 'period_duration' ),
output_field=DecimalField()))
Это дает мне правильный результат:
Decimal('8.01917989417989E-10')
Однако, если заменить 485.00
на 485
:
result.annotate(test=ExpressionWrapper( 485 / F( 'period_duration' ),
output_field=DecimalField()))
Я получаю:
Decimal('0')
Это не было бы проблемой, если бы не то, что 485 также приходит из поля, называемого "value
". Мой запрос выглядит следующим образом:
result.annotate(test=ExpressionWrapper( F( 'value' ) / F( 'period_duration' ),
output_field=DecimalField()))
Value - это MoneyField, по сути, просто причудливая обертка вокруг DecimalField.
Я могу заставить своих пользователей всегда использовать правильные десятичные дроби (485.00
в отличие от 485
), что само по себе было бы плохим дизайном, но... даже тогда, если значение базы данных 485.00
, Django ведет себя так, как будто это 485
и таким образом возвращает 0
при выполнении математики с плавающей точкой.
Я пробовал Cast
присвоить значение DecimalField
, безрезультатно.
result.annotate( res=ExpressionWrapper(
Cast('value', output_field=DecimalField()) / F( 'period_duration' ),
output_field=DecimalField() )).last().res
Результат всегда:
Decimal('0')
Вместо правильного:
Decimal('8.01917989417989E-10')
Как заставить Django всегда использовать математику с плавающей точкой?
p.s. period_duration
- это 604800000000
, если это может быть полезно.
Вы уверены, что F( 'value' )
дает вам номер?
MoneyField хранит ваш атрибут value в двух колонках, поэтому F( 'value' )
может быть не тем, что вы ожидаете.
Можно попробовать F( 'value_amount' )
.