如何在Django模板中编写计算商品原价的公式price/(1-discount%)
在Django模板中计算商品原价(折扣前价格)
需求:已知商品折扣后价格(
price字段)和折扣百分比(sale字段,比如输入20代表20%折扣),需要通过公式原价 = 折扣后价格 / (1 - 折扣百分比/100)计算原价,并在Django模板中展示。模板示例:
<span class="old-price">{{......}} L.E</span>对应的Product模型代码:
class Product(models.Model): seasonChoices = (('summer','summer'),('winter','winter'),('both','both')) ageChoices = (('men','men'),('kids','kids')) name = models.CharField(max_length=100) category = models.ForeignKey(Category, on_delete=models.PROTECT) price = models.DecimalField(max_digits=6, decimal_places=0) description = models.TextField(max_length=200, default='no description for this model', null=True, blank=True) season = models.CharField(max_length=50, default="both", choices=seasonChoices) age = models.CharField(max_length=50, default="men", choices=ageChoices) sale = models.IntegerField() # 折扣百分比,比如20代表打8折 img1 = models.ImageField(upload_to='products/%y/%m/%d') img2 = models.ImageField(upload_to='products/%y/%m/%d', null=True, blank=True) img3 = models.ImageField(upload_to='products/%y/%m/%d', null=True, blank=True) img4 = models.ImageField(upload_to='products/%y/%m/%d', null=True, blank=True) size = models.ManyToManyField(Size) availability = models.BooleanField(default=True)
方法一:在模型中添加计算属性(推荐)
直接在Product模型里定义计算原价的属性,模板直接调用即可,逻辑集中还方便复用:
修改Product模型,添加original_price属性:
class Product(models.Model): # 原有字段保持不变 # ... @property def original_price(self): # 处理折扣为0的情况,避免除以0错误 if self.sale == 0: return self.price # 按公式计算原价 return self.price / (1 - self.sale / 100)
模板中直接使用:
<span class="old-price">{{ product.original_price|floatformat:0 }} L.E</span>
floatformat:0过滤器可以把结果转为整数,和你的price字段(decimal_places=0)格式匹配;如果需要保留小数,可调整参数,比如floatformat:2。
方法二:直接在模板中计算(不推荐,逻辑分散)
如果不想修改模型,也可以用Django内置过滤器在模板里计算,但可读性和维护性较差:
<span class="old-price"> {% if product.sale == 0 %} {{ product.price }} {% else %} {{ product.price|div:1|div:(1|sub:product.sale|div:100)|floatformat:0 }} {% endif %} L.E </span>
注意事项
- 必须处理
sale=0的情况,防止出现除以0的错误; - 如果
sale字段可能为空,要额外加判空逻辑,比如{% if product.sale is not None and product.sale != 0 %}; - 计算结果可通过
floatformat或int过滤器格式化,保证显示格式统一。
内容的提问来源于stack exchange,提问作者Omar Zezo
相关产品推荐
相关产品推荐

