Django技术问题:如何将单个字段设为折叠面板标题,其余字段为内容?
优化手风琴表格布局,遵循DRY原则的解决方案
嘿,我懂你现在的痛点——重复循环数据集不仅不符合DRY(Don't Repeat Yourself)原则,还会让代码冗余、维护起来麻烦。咱们只需要先把object.rate_set.all的数据按frequency字段分组,就能用一次循环搞定手风琴的标题和对应的内容啦!
步骤1:在视图层完成数据分组(推荐方案)
先在视图里对数据进行排序+分组,确保相同frequency的项被归类到一起,这样模板里就能直接用分组后的结果:
from itertools import groupby # 先按frequency排序,保证groupby能正确分组 sorted_rates = object.rate_set.all().order_by('frequency') # 按frequency字段分组,得到(频率值, 对应rate对象列表)的结构 grouped_rates = groupby(sorted_rates, key=lambda rate: rate.frequency) # 转成列表方便模板遍历 frequency_groups = [(freq, list(rate_items)) for freq, rate_items in grouped_rates]
把frequency_groups传到模板里就可以了。
步骤2:模板里一次循环生成手风琴
现在模板里只需要两层循环(外层循环分组,内层循环当前分组下的产品和价格),完全避免重复遍历整个rate集合:
<div class="accordion" id="frequencyAccordion"> {% for freq, rate_items in frequency_groups %} <div class="accordion-item"> <h2 class="accordion-header" id="heading-{{ forloop.counter }}"> <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-{{ forloop.counter }}"> {{ freq }} <!-- 手风琴标题:frequency值 --> </button> </h2> <div id="collapse-{{ forloop.counter }}" class="accordion-collapse collapse" aria-labelledby="heading-{{ forloop.counter }}" data-bs-parent="#frequencyAccordion"> <div class="accordion-body"> <table class="table"> <tbody> {% for item in rate_items %} <tr> <td>{{ item.product }}</td> <td>{{ item.price }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> {% endfor %} </div>
为什么这个方案更好?
- 只执行一次数据库查询,排序在数据库层面完成,性能更优
- 模板代码逻辑清晰,完全遵循DRY原则,没有重复遍历数据集
- 后续维护时,只需要修改一处逻辑即可,降低出错概率
内容的提问来源于stack exchange,提问作者Cam Shan
相关产品推荐
相关产品推荐

