Python 为什么Django decimal max_digits验证会因奇怪的行为而失败?
我有一个模型字段,相当于全职Python 为什么Django decimal max_digits验证会因奇怪的行为而失败?,python,django,Python,Django,我有一个模型字段,相当于全职 full_time_equivalent = models.DecimalField( max_digits=5, decimal_places=2, default=100, validators=[ MinValueValidator(Decimal(0)), MaxValueValidator(Decimal(100)) ] ) 为确保验证程序启动,我已使用以下命令覆盖保存: def s
full_time_equivalent = models.DecimalField(
max_digits=5,
decimal_places=2,
default=100,
validators=[
MinValueValidator(Decimal(0)),
MaxValueValidator(Decimal(100))
]
)
为确保验证程序启动,我已使用以下命令覆盖保存:
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.']
我做错了什么?十进制值10.01
不能精确地表示为浮点数。当值转换为十进制时,您将得到十进制('10.009999999999977868371792719699442386627197265625')
,这与十进制('10.01')
,非常接近,但未通过最大位数验证
您可以通过在测试中使用字符串'10.01'
或十进制十进制('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')
)
查看了…如果只调用self.clean()
,会发生什么?只是想知道这个问题是从哪里来的。看起来像是浮点问题。如果是,那么它是django验证器中的一个bug(但它使用的是Decimal
类型,不应该有这样的问题),或者在您的类中获得10.01
参数。我想您可能需要添加一些舍入。在python shell中,当我键入print(Decimal(10.01))
时,我得到了与您一样的10.009999…
。我想知道这是否有助于Decimal(10.01).量化(Decimal(10)**-2))
注意,通过在save()
中调用full\u clean()
,您将在使用模型表单的地方(如Django admin)运行两次验证。