英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论