【问题标题】:Django error: [<class 'decimal.InvalidOperation'>]Django 错误:[<class 'decimal.InvalidOperation'>]
【发布时间】:2019-10-20 20:42:35
【问题描述】:

我在我的项目中做了以下信号:

@receiver(pre_save, sender=group1)
@disable_for_loaddata
def total_closing_group1(sender,instance,*args,**kwargs):
    total_group_closing_deb_po = instance.master_group.filter(ledgergroups__Closing_balance__gte=0,balance_nature='Debit').aggregate(the_sum=Coalesce(Sum('ledgergroups__Closing_balance'), Value(0)))['the_sum']
    total_group_closing_deb_neg = instance.master_group.filter(ledgergroups__Closing_balance__lt=0,balance_nature='Debit').aggregate(the_sum=Coalesce(Sum('ledgergroups__Closing_balance'), Value(0)))['the_sum']
    total_group_closing_po_cre = instance.master_group.filter(ledgergroups__Closing_balance__gte=0,balance_nature='Credit').aggregate(the_sum=Coalesce(Sum('ledgergroups__Closing_balance'), Value(0)))['the_sum']
    total_group_closing_neg_cre = instance.master_group.filter(ledgergroups__Closing_balance__lt=0,balance_nature='Credit').aggregate(the_sum=Coalesce(Sum('ledgergroups__Closing_balance'), Value(0)))['the_sum']
    total_closing_deb_po = instance.ledgergroups.filter(Closing_balance__gte=0,group1_Name__balance_nature='Debit').aggregate(the_sum=Coalesce(Sum('Closing_balance'), Value(0)))['the_sum']
    total_closing_deb_ne = instance.ledgergroups.filter(Closing_balance__lt=0,group1_Name__balance_nature='Debit').aggregate(the_sum=Coalesce(Sum('Closing_balance'), Value(0)))['the_sum']
    total_closing_cre_po = instance.ledgergroups.filter(Closing_balance__gte=0,group1_Name__balance_nature='Credit').aggregate(the_sum=Coalesce(Sum('Closing_balance'), Value(0)))['the_sum']
    total_closing_cre_ne = instance.ledgergroups.filter(Closing_balance__lt=0,group1_Name__balance_nature='Credit').aggregate(the_sum=Coalesce(Sum('Closing_balance'), Value(0)))['the_sum']
    if total_group_closing_deb_po != None and total_group_closing_neg_cre != None and total_closing_deb_po != None and total_closing_cre_ne != None:
        instance.positive_closing = total_group_closing_deb_po + abs(total_group_closing_neg_cre) + total_closing_deb_po + abs(total_closing_cre_ne)
    if total_group_closing_po_cre != None and total_group_closing_deb_neg != None and total_closing_cre_po != None and total_closing_deb_ne != None:    
        instance.negative_closing = total_group_closing_po_cre + abs(total_group_closing_deb_neg) + total_closing_cre_po + abs(total_closing_deb_ne)

我的模型是:

class Group1(models.Model):   
    group_name = models.CharField(max_length=32)    
    master = models.ForeignKey("self",on_delete=models.CASCADE,related_name='master_group',null=True)    
    negative_closing = models.DecimalField(max_digits=10,default=0,decimal_places=2,null=True)    
    positive_closing = models.DecimalField(max_digits=10,default=0,decimal_places=2,null=True)


class Ledger1(models.Model):
    name            = models.CharField(max_length=32)
    group1_name     = models.ForeignKey(Group1,on_delete=models.CASCADE,null=True,related_name='ledgergroups')
    closing_balance = models.DecimalField(default=0.00,max_digits=10,decimal_places=2,blank=True)

一开始它工作得很好,但是当我通过将数据放入字段来增加数据库的负载时突然之间。

它向我抛出了错误[&lt;class 'decimal.InvalidOperation'&gt;]

这个错误意味着什么?

任何人都知道

谢谢

【问题讨论】:

  • code.djangoproject.com/ticket/24636 请阅读此主题。我认为这正是您所需要的。
  • 是的,这是确切的解决方案,但是如何在不更改 django 项目中的内置文件的情况下安全地使用这个十进制验证器
  • negative_closing = models.DecimalField(max_digits=10,default=0,decimal_places=2,null=True) 为您的十进制字段创建自定义验证器。
  • 问题出在max_digitdecimal_places吗?

标签: django django-models django-signals


【解决方案1】:

我最近自己也遇到了这个问题。就我而言,我认为我了解十进制字段的方式是错误的。

我以为 max_digits=x 为整数部分提供 x 值,而 decimal_places=y 为小数部分提供 y 值,但我错了。

max_digits 定义总数。总位数和小数位数是 max_digits 的一部分。

例如。如果 max_digits=13decimal_places=3 则该字段将存储最多十亿的数值,其中包含 3 个精确的小数。

这可能会帮助像我过去几个小时一样陷入困境的人。

【讨论】:

  • 我想你不小心说错了。 max_digits=13 和 decimal_places=3 最大 10 亿的数值,小数点后 3 位,对吧?
  • 对不起,我的错。我以为我说清楚了,但我错误地输入了错误。谢谢你让我知道。我已经更新了我的答案。
  • 我在通过 FactoryBoy 使用 Faker 生成小数时遇到了这个问题。 Faker 使用 left_digits 和 right_digits。在 Django 中,left_digits + right_digits 不应超过字段的 max_digits,理想情况下,right_digits 应与 decimal_places 相同。
  • @Anjaan - 我在理解上犯了同样的错误。感谢您解决这个问题
【解决方案2】:

我遇到了类似的问题,我解决这个问题的方法是确保我要保存的值适合该字段,两件事:

  1. 首先,使用round(myValueFloat, 4)。就是为了减少我尝试保存的十进制数。
  2. 对我无法减少的值使用更大的字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    相关资源
    最近更新 更多