Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么Django decimal max_digits验证会因奇怪的行为而失败?_Python_Django - Fatal编程技术网

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)运行两次验证。