Django的normalize()显示为1E+1。

huangapple go评论49阅读模式
英文:

Django normalize() is showing 1E+1

问题

我正在尝试在我的模型中创建一个函数来显示产品信息,而在我的模型中,我有以下内容:

class Product(models.Model):
    price = models.DecimalField(max_digits=10, decimal_places=2)

    @property
    def product_label(self):
        return f'该产品价格为 {self.price.normalize()}'

如果价格类似于10.50,则使用normalize()可以正常工作。输出如下,这正是我想要的:

> 该产品价格为 10.05

但是,当价格为10.00时,显示的输出会显示1E+1而不是10

> 该产品价格为 1E+1

有什么办法可以解决这个问题吗?

英文:

I'm trying to create a function in my model to display product info, and in my model I have the following:

class Product(models.Model):
    price = models.DecimalField(max_digits=10, decimal_places=2)

    @property
    def product_label(self):
	return f'The product price is {self.price.normalize()}'

Using normalize() is working fine if the price is something like 10.50
The output is as the following, which is what I exactly want:

> The product price is 10.05

BUT when I have a price like 10.00, the output displayed shows 1E+1 instead of 10

> The product price is 1E+1

Is there any idea how can I fix this issue?

答案1

得分: 1

解决方法

你可以这样修复它:

    @property
    def product_label(self):
        return f'产品价格为 {self.price.normalize():f}';

只需在方法调用后添加 :f ,以将 Decimal 对象格式化为定点数。

解释

来自文档:

> normalize(context=None)
>
> 通过去除最右边的尾随零并将任何等于 Decimal('0') 的结果转换为 Decimal('0e0') 来规范化数字。用于为等价类的属性生成规范值。例如,Decimal('32.100')Decimal('0.321000e+2') 都规范化为等效值 Decimal('32.1')

所以,它不一定转换为可读的值。

在 FAQ 部分,你可以看到一些提供的解决方案,如这个:

> 如果应用程序不关心跟踪有效数字,可以轻松地去掉指数和尾随零,失去有效数字,但保持值不变:
>
> >>> from decimal import Decimal
> >>> def remove_exponent(d):
> ... return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
> >>> remove_exponent(Decimal('5E+3'))
> Decimal('5000')

但在你的情况下,只需要格式化值即可。

参考

格式规范符

https://peps.python.org/pep-3101/#standard-format-specifiers

Decimal FAQ

https://docs.python.org/3/library/decimal.html#decimal-faq

英文:

Solution

You can fix it this way:

@property
def product_label(self):
    return f'The product price is {self.price.normalize():f}'

Just by adding :f after the method call, to format the Decimal object as fixed-point number.

Explanation

From the documentation:

> normalize(context=None)
>
> Normalize the number by stripping the rightmost trailing zeros and converting any result equal to Decimal('0') to Decimal('0e0'). Used for producing canonical values for attributes of an equivalence class. For example, Decimal('32.100') and Decimal('0.321000e+2') both normalize to the equivalent value Decimal('32.1').

So, it's not necessarily converting to a human-readable value.

In the FAQ section you can see some solutions provided like this one:

> If an application does not care about tracking significance, it is easy to remove the exponent and trailing zeroes, losing significance, but keeping the value unchanged:
>
> >>> from decimal import Decimal
> >>> def remove_exponent(d):
> ... return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
> >>> remove_exponent(Decimal('5E+3'))
> Decimal('5000')

But in your case, it's enough to format the value.

Reference

Format specifiers

https://peps.python.org/pep-3101/#standard-format-specifiers

Decimal FAQ

https://docs.python.org/3/library/decimal.html#decimal-faq

huangapple
  • 本文由 发表于 2023年5月25日 17:14:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76330653.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定