如何让Django Rest Framework将小数舍入到最大精度?

时间:2017-10-26 08:40:43

标签: django-rest-framework decimal rounding

我有一个带有DecimalField的Django Rest Framework序列化程序

serializers.DecimalField(max_digits=9, decimal_places=6)

现在,如果我尝试反序列化包含具有更高精度的小数的数据(即50.1234567),则序列化程序会引发ValidationError:

"Ensure that there are no more than 6 decimal places."

如果最后一位数为0,甚至会发生这种情况。是否可以使串行器将给定值舍入到最大精度(即50.1234567到50.123457)?如果是这样的话?

2 个答案:

答案 0 :(得分:8)

在将输入强制转换为Decimal后,DecimalField会验证恰当命名但未记录的validate_precision方法中的值的精度。因此,要禁用此验证,可以覆盖此方法并只返回输入值:

class RoundingDecimalField(serializers.DecimalField):
    def validate_precision(self, value):
        return value

事实证明,这样做足以获得所需的舍入行为。

调用validate_precision之后,DecimalField调用quantize,这将"将十进制值量化为配置的精度" (来自docstring)。

此量化过程的舍入模式由当前有效的十进制上下文控制。

如果需要特定的舍入模式,可以使用django-rest-framework-braces中的(再次未记录的)drf_braces.fields.custom.RoundedDecimalField字段。此字段采用可选的舍入参数,其中可以指定所需的rounding mode

答案 1 :(得分:0)

感谢答案,@ jaap3。想在这里添加我的实现,以供其他发现此问题的人参考。以下是我在另一个序列化程序类中使用此舍入字段的方法,该字段具有我想要舍入到位置模型上设置的max_digits值的属性。

class RoundingDecimalField(serializers.DecimalField):
"""Used to automaticaly round decimals to the model's accepted value."""

    def validate_precision(self, value):
        return value


class PositionSerializer(serializers.HyperlinkedModelSerializer):

    url = serializers.HyperlinkedIdentityField(
        view_name='target_position-detail')

    price = RoundingDecimalField(max_digits=21, decimal_places=14)