Django模板有序列表条目均显示1的问题修复及并列排名实现
有序列表全部显示数字1的修复方案
原因
你把<ol>标签放在了模板的{% for %}循环内部,每遍历一个商品就生成一个新的有序列表,每个<li>都是所在列表的第一个元素,所以全部显示数字1。
修复代码
修改reports.html的列表渲染部分,将<ol>移到循环外面:
<section style="color: black;"> <h2>Top 3 Purchases</h2> <ol> {% for item in list_of_purchases %} <li>{{ item }}</li> {% endfor %} </ol> </section>
实现并列条目显示相同排名的功能
当前你只传递了商品名称列表到模板,缺少销量和排名数据,需要在视图层先计算带排名的商品数据:
1. 修改views.py,计算带并列排名的商品数据
更新get_context_data方法,保留销量并计算并列排名:
class ReportView(LoginRequiredMixin, TemplateView): template_name = "inventory/reports.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["purchases"] = Purchase.objects.all() revenue = Purchase.objects.aggregate( revenue=Sum("menu_item__price"))["revenue"] total_cost = 0 for purchase in Purchase.objects.all(): for recipe_requirement in purchase.menu_item.reciperequirement_set.all(): total_cost += recipe_requirement.ingredient.unit_price * \ recipe_requirement.quantity purchases = Purchase.objects.values( 'timestamp', item_name=F('menu_item__name'), item_price=F('menu_item__price'), item_desc=F('menu_item__description')) df = read_frame(purchases) grouped_purchases = df.groupby('item_name')[ 'timestamp'].count().reset_index() # 重命名销量列,更直观 grouped_purchases.rename(columns={'timestamp': 'sales_count'}, inplace=True) # 按销量降序排序 sort_purchases = grouped_purchases.sort_values("sales_count", axis=0, ascending=False, ignore_index=True) # 计算并列排名:dense方法会让相同销量的商品拥有相同排名,且排名连续 sort_purchases['rank'] = sort_purchases['sales_count'].rank(method='dense', ascending=False).astype(int) # 筛选排名前3的所有商品(包含并列) top_3 = sort_purchases[sort_purchases['rank'] <= 3] # 转换成字典列表,方便模板渲染 top_purchases_with_rank = top_3.to_dict('records') context["revenue"] = revenue context["total_cost"] = total_cost context["profit"] = revenue - total_cost context["gross_profit"] = (revenue - total_cost) / total_cost * 100 context["gross_margin_ratio"] = (revenue - total_cost) / revenue * 100 # 替换原有列表为带排名的数据 context["top_purchases_with_rank"] = top_purchases_with_rank return context
2. 修改reports.html,渲染排名和商品
<section style="color: black;"> <h2>Top 3 Purchases</h2> <ol> {% for item in top_purchases_with_rank %} <li>{{ item.rank }}. {{ item.item_name }} (销量: {{ item.sales_count }})</li> {% endfor %} </ol> </section>
如果不需要显示销量,直接去掉(销量: {{ item.sales_count }})即可。
内容的提问来源于stack exchange,提问作者CodingSexagenarian
相关产品推荐
相关产品推荐

