我有一个带有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)?如果是这样的话?
答案 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)