Django自定义模型方法传参:租车应用按时长展示车辆价格
如何将duration传入模型方法并正确计算车辆租赁价格
嘿,咱们一步步来解决这个问题:首先你当前的VehicleCategory模型里的price方法有个语法问题,然后再调整视图逻辑,把计算好的duration传给模型方法,最后在模板里展示结果。
1. 先修正模型里的价格计算方法
你用了@property装饰器,但这个装饰器的方法是不能接收额外参数的,所以def price(self, duration)会报错。咱们把它改成普通的实例方法,这样就能接收duration参数了,顺便优化一下查询效率(别全查所有VehiclePrice记录,直接用ORM过滤更高效):
# models.py class VehicleCategory(models.Model): # 假设你继承了models.Model,这里补上必要的父类 title = models.CharField(max_length=100) main_category = models.CharField(max_length=50) # 其他字段... def get_price(self, duration): # 过滤当前类别且时长在对应档位内的价格记录 matching_price = VehiclePrice.objects.filter( vehicle_category__title=self.title, slab__start__lte=duration, slab__end__gte=duration ).first() # 有匹配就返回价格,没有就返回None(可以根据需求调整默认值) return matching_price.net_price if matching_price else None
2. 在视图中把duration传给每个车辆类别
你已经算出了duration,现在需要把这个值传给每个VehicleCategory实例,计算对应的价格,然后把类别和价格一起放到context里:
# views.py from django.shortcuts import render from datetime import datetime class HomeView(ListView): template_name = 'app/home.html' def get(self, request): start_date = request.GET.get('start_date') end_date = request.GET.get('end_date') # 先初始化基础的context内容 context = { 'form': CartQuantityForm(), 'dateform': DateForm() } if start_date and end_date: # 转换日期格式并计算时长 start_date = datetime.strptime(start_date, "%m/%d/%Y").date() end_date = datetime.strptime(end_date, "%m/%d/%Y").date() duration = (end_date - start_date).days + 1 # 获取两类车辆,为每个类别计算对应价格 e_cycles = VehicleCategory.objects.filter(main_category='E-Cycle') e_scooters = VehicleCategory.objects.filter(main_category='E-Scooter') # 把类别和价格打包成字典列表,方便模板渲染 context['vehiclecategory1'] = [ {'category': category, 'rental_price': category.get_price(duration)} for category in e_cycles ] context['vehiclecategory2'] = [ {'category': category, 'rental_price': category.get_price(duration)} for category in e_scooters ] return render(request, self.template_name, context)
3. 在模板里展示类别和对应的价格
现在你可以在home.html模板里遍历这些数据,展示每个类别的名称和价格了:
<!-- 展示E-Cycle类别 --> <h3>E-Cycle 可选车型</h3> {% for item in vehiclecategory1 %} <div class="vehicle-card"> <h4>{{ item.category.title }}</h4> <p class="price">租赁价格:${{ item.rental_price }}</p> <!-- 这里可以添加其他车辆信息,比如图片、描述等 --> </div> {% empty %} <p>当前时间段暂无可用的E-Cycle</p> {% endfor %} <!-- 展示E-Scooter类别 --> <h3>E-Scooter 可选车型</h3> {% for item in vehiclecategory2 %} <div class="vehicle-card"> <h4>{{ item.category.title }}</h4> <p class="price">租赁价格:${{ item.rental_price }}</p> </div> {% empty %} <p>当前时间段暂无可用的E-Scooter</p> {% endfor %}
一些额外的优化建议
- 给
VehiclePrice模型添加唯一约束,确保每个车辆类别和时长档位的组合只有一条价格记录,避免出现多条匹配的情况:# models.py class VehiclePrice(models.Model): vehicle_category = models.ForeignKey(VehicleCategory, on_delete=models.CASCADE) slab = models.ForeignKey(Slab, on_delete=models.CASCADE) net_price = models.DecimalField(max_digits=10, decimal_places=2) class Meta: unique_together = ('vehicle_category', 'slab') - 如果用户选择的时长超出了所有预设的档位,记得在模板里处理
rental_price为None的情况,比如显示"暂无对应时长的价格"。
内容的提问来源于stack exchange,提问作者san
相关产品推荐
相关产品推荐

