为什么Django decimal max_digits验证失败并出现奇怪的行为?

时间:2017-10-19 14:18:48

标签: python django

我有一个模型字段full_time_equivalent

full_time_equivalent = models.DecimalField(
    max_digits=5,
    decimal_places=2,
    default=100,
    validators=[
        MinValueValidator(Decimal(0)),
        MaxValueValidator(Decimal(100))
    ]
)

为了确保验证者触发,我已使用以下内容覆盖save

def save(self, *args, **kwargs):
    # Run validations
    self.full_clean()
    return super().save(*args, **kwargs)

通过以下测试:

    project2_membership = ProjectMembership(
        user=self.new_user,
        project=project2,
        is_project_manager=False,
        full_time_equivalent=10.01
    )

当我进入验证时,会显示以下值并显示相应的错误:

Decimal('10.0099999999999997868371792719699442386627197265625')


django.core.exceptions.ValidationError: 
{'full_time_equivalent': ['Ensure that there are no more than 5 digits in total.']

我做错了什么?

1 个答案:

答案 0 :(得分:2)

小数值10.01不能完全表示为浮点数。当值转换为小数时,最终会得到Decimal('10.0099999999999997868371792719699442386627197265625'),这几乎等于Decimal('10.01'),但未通过max_digits验证。

您可以在测试中使用字符串'10.01'或小数Decimal('10.01')来阻止错误。

from decimal import Decimal

project2_membership = ProjectMembership(
    user=self.new_user,
    project=project2,
    is_project_manager=False,
    full_time_equivalent=Decimal('10.01')
)