我的模型上有以下字段:
class Range(models.Model):
optimal_low = models.DecimalField(max_digits=30, decimal_places=8)
optimal_high = models.DecimalField(max_digits=30, decimal_places=8)
以下是我如何将它们带入表单中(因为表单的主要对象不是此模型,我只需要字段,并且不想复制max_digits和decimal_places
class ReadingMappingForm(forms.ModelForm):
optimal_low = Range._meta.get_field('optimal_low').formfield()
optimal_high = Range._meta.get_field('optimal_high').formfield()
似乎django允许以开箱即用的科学记数法输入小数,但是有一个小于某个阈值的小故障。
在表单中,如果我输入 1.5E9 ,它可以正常工作,并将值保存为 1500000000.00000000 (此处为online scientific notation calculator)
但是,如果我输入 1.5E10 ,则说:
确保小数位数不超过8个。
哪个错了,因为我没有添加任何小数位。事实上,如果我以正常表示法输入 1.5E10 ,即使添加了8位小数,即 15000000000.00000000 ,它也能正常工作。
所以我觉得有些事情在幕后工作不正确......
修改
我在控制台中测试了该字段,并在那里出现错误:
from django.forms import DecimalField
>>> f = DecimalField(max_digits=30, decimal_places=8)
>>> f.clean('1.5E9')
Decimal('1.5E+9')
>>> f.clean('1.5E10')
Traceback (most recent call last):
File "myproject/env/lib/python3.5/site-packages/django/core/management/commands/shell.py", line 69, in handle
self.run_shell(shell=options['interface'])
File "myproject/env/lib/python3.5/site-packages/django/core/management/commands/shell.py", line 61, in run_shell
raise ImportError
ImportError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "myproject/env/lib/python3.5/site-packages/django/forms/fields.py", line 168, in clean
self.run_validators(value)
File "myproject/env/lib/python3.5/site-packages/django/forms/fields.py", line 157, in run_validators
raise ValidationError(errors)
django.core.exceptions.ValidationError: ['Ensure that there are no more than 8 decimal places.']
答案 0 :(得分:1)
它似乎是DecimalValidator中的错误,具有以下解释
您声明的数字 1.5E10 被解析为具有属性_int '15'
和_exp 9
的对象
在DecimalValidator __call__
方法中,小数位数计算为
decimals = abs(exponent)
除此之外还会触发以下
if self.decimal_places is not None and decimals > self.decimal_places:
raise ValidationError(
self.messages['max_decimal_places'],
code='max_decimal_places',
params={'max': self.decimal_places},
)
似乎修复以下内容就像是
if exponent < 0:
decimal = abs(exponent)
else:
decimal = 0
修复版本2.0如下所示
# If the absolute value of the negative exponent is larger than the # number of digits, then it's the same as the number of digits, # because it'll consume all of the digits in digit_tuple and then # add abs(exponent) - len(digit_tuple) leading zeros after the # decimal point. if abs(exponent) > len(digit_tuple): digits = decimals = abs(exponent) else: digits = len(digit_tuple) decimals = abs(exponent)
答案 1 :(得分:0)
这是一个已知的bug,它是固定的,但据我所知,只在django 2.0中。