Django编写QuerySet实现健身房价格表展示结果异常如何解决?
问题根源
- 视图层返回的
plans1和dfeatures1都是未去重的Price查询集:同一个订阅计划会对应多条不同功能的Price记录,所以表头会出现重复的计划名称,功能行也会重复输出。 - 模板渲染时没有关联当前行的功能和当前列的订阅计划:直接输出
plan.price只会拿到当前循环的plan对象的价格,和当前行的功能完全没有匹配关系,导致同一行所有列的价格一致。 - 补充注意:你提供的
Price模型中未定义gender字段,若实际业务需要按性别筛选价格,请自行在Price模型中补充该字段定义。
修改方案
1. 重写视图层逻辑
先单独拉出去重的订阅计划、功能列表,再构造一个二维价格映射表,方便模板快速取值:
def pricing(request,slug): gym = models.Gym.objects.get(slug=slug) banners = models.Banners.objects.filter(gym=gym) # 先拿到当前健身房男性适用的所有Price记录 man_prices = models.Price.objects.filter(gender='man', gym=gym).select_related('subplan', 'feature') # 去重拿到所有订阅计划 plans = list({p.subplan for p in man_prices}) # 去重拿到所有功能项 features = list({p.feature for p in man_prices}) # 构造价格映射表:key为(功能id, 订阅计划id),value为对应价格 price_map = {(p.feature.id, p.subplan.id): p.price for p in man_prices} return render(request, 'pricing.html', { 'plans': plans, 'features': features, 'price_map': price_map, 'gym': gym, 'banners': banners })
2. 修改模板渲染逻辑
按照新的传参调整模板取值逻辑,匹配对应功能和计划的价格:
<thead> <tr> <th style="width: 34%;"></th> {% for plan in plans %} <th style="width: 22%;">{{plan.title}}</th> {% endfor %} </tr> </thead> <tbody> {% for feature in features %} <tr> <th scope="row" class="text-start">{{feature.title}}</th> {% for plan in plans %} <td> {{ price_map|get_item:(feature.id, plan.id) }} Azn. </td> {% endfor %} </tr> {% endfor %} </tbody>
注意:模板中要用到自定义过滤器
get_item来从字典中取值,你需要在app下新建templatetags目录,新增自定义过滤器代码:from django import template register = template.Library() @register.filter def get_item(dictionary, key): return dictionary.get(key)新增后需要在模板开头加上
{% load 你的自定义过滤器文件名 %}才能正常使用。
内容的提问来源于stack exchange,提问作者Fuad Jabbarov
相关产品推荐
相关产品推荐

