Django模板高效展示仅单列差异的多数据表方案问询
高效实现双表格渲染方案
当然有更高效的方式!你现在的做法需要在模板里反复循环和判断,数据量大的时候确实会拖慢渲染速度。我们可以把数据整理的工作移到后端完成,让模板只负责简单的渲染,这样能大幅提升效率。
方案一:后端预处理为扁平结构(最适合固定两种scoreType的场景)
首先在视图层,把每个问题的初始分和当前分直接映射好,生成一个新的列表结构:
# 修改你的视图代码 questions = Question.objects.prefetch_related(Prefetch('answer_set', to_attr='answers')).all() # 预处理数据,把每个问题的两种分数整合到一个字典里 questions_with_scores = [] for question in questions: # 用字典快速映射scoreType到对应的分数 score_dict = {ans.scoreType: ans.score for ans in question.answers} questions_with_scores.append({ 'question_text': question.question, 'initial_score': score_dict.get(1), # 1对应'initial'类型 'current_score': score_dict.get(2) # 2对应'current'类型 }) # 把处理好的数据传给模板 return render(request, 'your_template.html', {'questions_with_scores': questions_with_scores})
然后在模板里,只需要遍历一次预处理好的数据,就能分别渲染两个表格:
<!-- Initial Scores 表格 --> <h3>Initial Scores</h3> <table border="1"> <thead> <tr> <th>Question</th> <th>Score</th> </tr> </thead> <tbody> {% for item in questions_with_scores %} <tr> <td>{{ item.question_text }}</td> <td>{{ item.initial_score }}</td> </tr> {% endfor %} </tbody> </table> <!-- Current Scores 表格 --> <h3>Current Scores</h3> <table border="1"> <thead> <tr> <th>Question</th> <th>Score</th> </tr> </thead> <tbody> {% for item in questions_with_scores %} <tr> <td>{{ item.question_text }}</td> <td>{{ item.current_score }}</td> </tr> {% endfor %} </tbody> </table>
这种方式的优势是:后端只做一次数据整理,模板里没有复杂的判断逻辑,渲染时只需要遍历一次数据生成两个表格,相比原来的多次循环判断,性能提升非常明显,尤其数据量大的时候。
方案二:通用分组方案(适合scoreType可能扩展的场景)
如果以后可能增加更多的scoreType,比如加上'final'分数,那可以用通用的分组方式,自动按scoreType分类:
# 视图层通用分组处理 questions = Question.objects.prefetch_related(Prefetch('answer_set', to_attr='answers')).all() # 按scoreType的标签分组,比如'initial'、'current' score_groups = {} # 先拿到scoreType的标签映射,方便直接用名称 score_type_labels = dict(Answer.SCORETYPES) for question in questions: for answer in question.answers: # 获取当前分数类型的标签 score_label = score_type_labels[answer.scoreType] # 如果这个标签还没在分组里,初始化一个列表 if score_label not in score_groups: score_groups[score_label] = [] # 添加当前问题和分数到对应分组 score_groups[score_label].append({ 'question_text': question.question, 'score': answer.score }) # 传给模板 return render(request, 'your_template.html', {'score_groups': score_groups})
模板里就可以自动渲染所有分组的表格,不用手动写多个表格:
{% for label, scores in score_groups.items %} <h3>{{ label }} Scores</h3> <table border="1"> <thead> <tr> <th>Question</th> <th>Score</th> </tr> </thead> <tbody> {% for item in scores %} <tr> <td>{{ item.question_text }}</td> <td>{{ item.score }}</td> </tr> {% endfor %} </tbody> </table> {% endfor %}
这种方式的灵活性更高,不管以后加多少种scoreType,模板都能自动适配,而且同样只需要后端一次处理,模板渲染效率很高。
内容的提问来源于stack exchange,提问作者Alexander Schillemans
相关产品推荐
相关产品推荐

