在看<<django by example>>的第八章利用paypal付款那里报错
AttributeError: 'int' object has no attribute 'quantize'
错误代码定位提示为views.py中
'amount': '%.2f' % order.get_total_cost().quantize(Decimal('.01')),
解决方法很简单将语句改为
'amount': '%.2f' % Decimal(order.get_total_cost()).quantize(Decimal('.01'))
但找到个很有意思的事,可以先看相关语句(只放出了函数语句,和Model的具体语句)
class Product(models.Model): price = models.DecimalField(max_digits=10, decimal_places=2)
class Order(models.Model): def get_total_cost(self): return sum(item.get_cost() for item in self.items.all()) class OrderItem(models.Model): price = models.DecimalField(max_digits=10, decimal_places=2) quantity = models.PositiveIntegerField(default=1) def get_cost(self): return self.price * self.quantity
报错很容易看出就是因为order.get_total_cost()的值为int型,需要进行Decimal()转换一下类型,但我一开始并不明白为什么会得到int型的值,我又向前查找,找到这个get_total_cost()方法的位置
我发现IDE在self.price * self.quantity这里的*会有个提示Class 'DecimalField' does not define '__mul__', so the '*' operator cannot be used on its instances,我理解了后半句,但前半句并找不到解释
然后我想到可以更改get_cost()方法,改为
return Decimal(self.price) * Decimal(self.quantity)
有意思的是报错仍然存在,即使在Decimal()更改类型计算后,再sum求和返回get_total_cost(self)得到的值仍然为int型,我觉得为了避免这种情况你可以在函数里直接返回数据时就直接进行Decimal(),总好过于在使用的时候忘记使用Decimal()
推荐更改Class Order里的方法也不要在使用的时候再更改,如下
def get_total_cost(self): return Decimal(sum(item.get_cost() for item in self.items.all()))