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


评论