如何在Django视图与模板中正确展示各商品的过期剩余天数
Django中商品剩余过期天数显示一致问题的解决
问题原因
你代码的核心问题在于视图函数中循环计算剩余天数时,每次都会覆盖全局的days_left变量,最终传入模板的仅仅是最后一个商品的剩余天数。模板循环所有商品时,都引用这个单一的全局变量,所以所有商品显示的天数完全相同。
解决方案
下面提供两种可行的修复方案,推荐第二种将逻辑封装在模型中的写法,更符合Django的设计思想。
方案一:在视图中为每个商品绑定剩余天数属性
修改视图函数,遍历商品时为每个对象新增days_left属性,将计算结果绑定到对应商品上:
from datetime import date def days_left_for_expiry(expiry_date): # 处理过期日期为空的边界情况 if not expiry_date: return "无过期日期" today = date.today() delta = expiry_date - today # 区分未过期和已过期状态 return str(delta.days) if delta.days >= 0 else "已过期" def home(request): products = Product.objects.all() for product in products: product.days_left = days_left_for_expiry(product.itemexpdate) return render(request,'store/dashboard.html',{'products': products})
修改模板,循环时直接调用每个商品自身的days_left属性:
{% for product in products %} <tr> <td>{{ product.itemname }}</td> <td>{{ product.itemexpdate }}</td> <td><b>{{ product.days_left }}</b></td> </tr> {% endfor %}
方案二:在模型中封装剩余天数计算逻辑(推荐)
将剩余天数的计算逻辑封装到Product模型中,通过@property装饰器定义只读属性,代码更简洁且易于维护:
from datetime import date class Product(models.Model): category = models.ForeignKey('store.Category',on_delete=models.CASCADE,default='SYRUP') itemname = models.CharField(max_length=50,blank=True,null=True) itemexpdate = models.DateField(auto_now_add=False, auto_now=False,blank=True,null=True) @property def days_left(self): if not self.itemexpdate: return "无过期日期" today = date.today() delta = self.itemexpdate - today return str(delta.days) if delta.days >= 0 else "已过期" class Category(models.Model): name = models.CharField(max_length=200,blank=True)
视图函数简化为直接查询所有商品:
def home(request): products = Product.objects.all() return render(request,'store/dashboard.html',{'products': products})
模板代码和方案一一致,直接使用{{ product.days_left }}获取对应商品的剩余过期天数。
内容的提问来源于stack exchange,提问作者Mukesh Chinna
相关产品推荐
相关产品推荐

