Django模板双重循环中通过两个外键获取对应Scoring模型的score值
解决方案
方案1:视图层预构造分数映射表(推荐,性能最优)
该方案仅需1次额外查询拉取全量打分数据,避免循环内反复访问数据库,适合绝大多数业务场景。
步骤1:修改views.py逻辑
from collections import defaultdict from .models import Question, Vendor, Scoring def index(request): questions = Question.objects.all() vendors = Vendor.objects.all() # 构造两层字典:第一层key为问题ID,第二层key为供应商ID,值为对应分数 score_map = defaultdict(dict) for score_obj in Scoring.objects.all(): q_id = score_obj.questionScoreForKey_id v_id = score_obj.vendorForKey_id if q_id and v_id: score_map[q_id][v_id] = score_obj.score return render(request, 'compare/index.html', { 'questions': questions, 'vendors': vendors, 'score_map': score_map })
步骤2:新增自定义模板过滤器(用于字典动态取值)
在你的应用目录下新建templatetags文件夹,新增空文件__init__.py,再新建custom_filters.py:
from django import template register = template.Library() @register.filter def get_item(dictionary, key): # 无对应分数时默认返回0,可根据需求调整默认值 return dictionary.get(key, 0)
步骤3:修改模板取值
模板顶部先加载自定义过滤器,再直接取对应值即可:
{% load custom_filters %} {% for ask in questions %} <tr> <td>{{ ask.questionText }} </td> {% for vend in vendors %} <td id="Vendor_{{ ask.pk }}_{{ vend.pk }}" style> {{ score_map|get_item:ask.pk|get_item:vend.pk }} </td> {% endfor %} </tr> {% endfor %}
方案2:专用查询过滤器(适合小数据量场景)
如果问题和供应商总数量少于100条,可以直接写专用查询过滤器,无需预构造映射表:
步骤1:新增分数查询过滤器
在templatetags/score_filters.py中编写:
from django import template from .models import Scoring register = template.Library() @register.filter def get_vendor_score(question, vendor): try: score_obj = Scoring.objects.get( questionScoreForKey=question, vendorForKey=vendor ) return score_obj.score except Scoring.DoesNotExist: return 0
步骤2:模板直接调用
{% load score_filters %} {% for ask in questions %} <tr> <td>{{ ask.questionText }} </td> {% for vend in vendors %} <td id="Vendor_{{ ask.pk }}_{{ vend.pk }}" style> {{ ask|get_vendor_score:vend }} </td> {% endfor %} </tr> {% endfor %}
注意:该方案每一轮循环都会发起一次数据库查询,数据量较大时性能会明显下降,仅适合测试或极小数据量场景。
内容的提问来源于stack exchange,提问作者kingbrain
相关产品推荐
相关产品推荐

