Django“DecimalFields必须定义'decimal_places'属性。”

时间:2016-04-19 15:50:37

标签: django

我的一个模型字段如下:

aaf_1kg_all = models.DecimalField(blank=True, null=True)

当我正常使用我的模型时,一切都很好。但是,当我在ready() hook中使用它时,我收到此错误:

SystemCheckError: System check identified some issues:

ERRORS:
myapp.Model.aaf_1kg_all: (fields.E130) DecimalFields must define a 'decimal_places' attribute.
myapp.Model.aaf_1kg_all: (fields.E132) DecimalFields must define a 'max_digits' attribute.

Django docs说这两个属性是可选的。我看到this answer,但在数据库中定义了小数位和max_digits。

如果我决定添加这些属性,即

aaf_1kg_all = models.DecimalField(blank=True, null=True, max_digits=10, decimal_places=10)

应用程序运行,但在某些时候我收到此错误:

Traceback (most recent call last):
[...]
  variants.extend(list(sub_qs))   # sub_qs is a QuerySet
File ".../django/db/models/query.py", line 258, in __iter__
  self._fetch_all()
File ".../django/db/models/query.py", line 1074, in _fetch_all
  self._result_cache = list(self.iterator())
File ".../django/db/models/query.py", line 68, in __iter__
  for row in compiler.results_iter(results):
File ".../django/db/models/sql/compiler.py", line 808, in results_iter
  row = self.apply_converters(row, converters)
File ".../django/db/models/sql/compiler.py", line 792, in apply_converters
  value = converter(value, expression, self.connection, self.query.context)
File ".../django/db/backends/sqlite3/operations.py", line 233, in convert_decimalfield_value
  value = expression.output_field.format_number(value)
File ".../django/db/models/fields/__init__.py", line 1608, in format_number
  return utils.format_number(value, self.max_digits, self.decimal_places)
File ".../django/db/backends/utils.py", line 200, in format_number
  value = value.quantize(decimal.Decimal(".1") ** decimal_places, context=context)
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

我忘记了什么吗?

3 个答案:

答案 0 :(得分:17)

您的max_digits应该大于decimal_places

请注意,0.1000000000使用10位数字,但1.0000000000使用11位数字。因此,如果您有max_digits=10decimal_places=10,则任何大于或等于1.0的数字都会出错。

如果您不需要小数位数,可能需要max_digits=10decimal_places=3之类的内容。或者,如果您确实需要decimal_places=10,那么您可能需要max_digits=12之类的内容,它可以支持小于1000的值。

Django 1.9添加了一个验证器来尝试防止这样的错误。有关详细信息,请参阅ticket 24636

答案 1 :(得分:8)

参数max_digits必须大于decimal_places

e.g

aaf_1kg_all = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)

答案 2 :(得分:0)

  

DECIMAL列不允许大于列定义所隐含范围的值。例如,DECIMAL(3,0)列支持-999到999的范围。DECIMAL(M,D)列允许小数点左边最多M-D位。

Mysql Documentation

如果要同时接受10位数字和小数位,则需要这样声明'aaf_1kg_all' decimal_places = 10)

aaf_1kg_all = models.DecimalField(blank=True, null=True, max_digits=20,  decimal_places=10)