* 不支持的操作数类型:'NoneType' 和 'decimal.Decimal'

unsupported operand type(s) for *: 'NoneType' and 'decimal.Decimal'

我正在尝试计算创建发票的小计、增值税和总计。我有一个错误

unsupported operand type(s) for *: 'NoneType' and 'decimal.Decimal'

models.py

class InvoiceLine(models.Model):

    TAX_RATE = (      
        (0, '20% (VAT on Expenses)'),
        (1, '5% (VAT on Expenses)'),
        (2, 'EC Aquisitions (20%)'),
        (3, 'EC Aquisitions (Zero Rated)'),
        (4, 'Exempt Expenses'),
        (5, 'No VAT'),
        (6, 'Reverse Charge Expenses (20%)'),
        (7, 'Zero Rated Expenses'),
    )


    invoice = models.ForeignKey(Invoice,related_name="has_lines",on_delete=models.CASCADE, blank=True, null=True, unique=False)
    invoice_item = models.CharField(max_length=100, verbose_name="Line")
    tax_rate = models.IntegerField(choices=TAX_RATE,default=0, blank=True, null=True)
    total = models.CharField(max_length=250, null=True, blank=True)
    description = models.CharField(max_length=100, blank=True, null=True)
    unit_price_excl_tax = models.DecimalField(max_digits=8,decimal_places=2, null=True, blank=True)
    quantity = models.DecimalField(max_digits=8,decimal_places=2,default=1, null=True, blank=True)
    unit_price = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)
    vat = models.CharField(max_length=250, null=True, blank=True)

    def subtotal(self):
        subtotal = Decimal(str(self.unit_price * self.quantity))
        return subtotal.quantize(Decimal('0.01'))

    def __unicode__(self):
        return self.description

subtotal 会计算单价 X 数量但是给我一个不支持的操作数类型错误。 然后,我将通过添加 20% 获得 total_lines 和增值税。

我可以使用它们来计算吗?

def total(self):
    total = Decimal(str(self.subtotal * (self.tax_rate/100)+ (self.tax_rate/100)))
    return total.quantize(Decimal('0.01'))

错误说您正在使用 * 操作,其中第一个数字实际上不是数字,而是 None

由于最后一个只是一个建议,我假设错误将出现在您第一次使用它时,当您计算小计时。

def subtotal(self):
    subtotal = Decimal(str(self.unit_price * self.quantity))
    return subtotal.quantize(Decimal('0.01'))

这意味着 unit_price 未设置,因此 None

您可以做不同的事情来避免错误。您可以为 unit_price 字段定义默认值:

class InvoiceLine(models.Model):

    TAX_RATE = (      
        (0, '20% (VAT on Expenses)'),
        (1, '5% (VAT on Expenses)'),
        (2, 'EC Aquisitions (20%)'),
        (3, 'EC Aquisitions (Zero Rated)'),
        (4, 'Exempt Expenses'),
        (5, 'No VAT'),
        (6, 'Reverse Charge Expenses (20%)'),
        (7, 'Zero Rated Expenses'),
    )


    invoice = models.ForeignKey(Invoice,related_name="has_lines",on_delete=models.CASCADE, blank=True, null=True, unique=False)
    invoice_item = models.CharField(max_length=100, verbose_name="Line")
    tax_rate = models.IntegerField(choices=TAX_RATE,default=0, blank=True, null=True)
    total = models.CharField(max_length=250, null=True, blank=True)
    description = models.CharField(max_length=100, blank=True, null=True)
    unit_price_excl_tax = models.DecimalField(max_digits=8,decimal_places=2, null=True, blank=True)
    quantity = models.DecimalField(max_digits=8,decimal_places=2,default=1, null=True, blank=True)
    unit_price = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True, default=0)
    vat = models.CharField(max_length=250, null=True, blank=True)

如果您在数据库级别不允许空值,您也可以防止出现空值:

class InvoiceLine(models.Model):

    TAX_RATE = (      
        (0, '20% (VAT on Expenses)'),
        (1, '5% (VAT on Expenses)'),
        (2, 'EC Aquisitions (20%)'),
        (3, 'EC Aquisitions (Zero Rated)'),
        (4, 'Exempt Expenses'),
        (5, 'No VAT'),
        (6, 'Reverse Charge Expenses (20%)'),
        (7, 'Zero Rated Expenses'),
    )


    invoice = models.ForeignKey(Invoice,related_name="has_lines",on_delete=models.CASCADE, blank=True, null=True, unique=False)
    invoice_item = models.CharField(max_length=100, verbose_name="Line")
    tax_rate = models.IntegerField(choices=TAX_RATE,default=0, blank=True, null=True)
    total = models.CharField(max_length=250, null=True, blank=True)
    description = models.CharField(max_length=100, blank=True, null=True)
    unit_price_excl_tax = models.DecimalField(max_digits=8,decimal_places=2, null=True, blank=True)
    quantity = models.DecimalField(max_digits=8,decimal_places=2,default=1, null=True, blank=True)
    unit_price = models.DecimalField(max_digits=8, decimal_places=2, null=False, blank=False)
    vat = models.CharField(max_length=250, null=True, blank=True)

或者,您可以保留此部分不变并检查您的小计计算:

def subtotal(self):
    if self.unit_price and self.quantity:
        subtotal = Decimal(str(self.unit_price * self.quantity))
        return subtotal.quantize(Decimal('0.01'))
    else:
        return None