You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中通过反向外键查询获取参数及对应选项的查询集?

问题描述

我定义了Parameter和ParameterChoices两个模型,每个Parameter对应多个ParameterChoices选项。我要实现一个评估功能,在HTML模板中展示参数列表,每个参数对应一组固定的可选选项(最终渲染效果如下)。要求不使用原生SQL查询,请问该怎么实现?

理想渲染效果:

<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>参数</th>
<th>可选选项</th>
</tr>
</thead>
<tbody>
<tr>
<td>参数1</td>
<td><code>选项A</code> <code>选项B</code> <code>选项C</code></td>
</tr>
<tr>
<td>参数2</td>
<td><code>选项Y</code> <code>选项Z</code></td>
</tr>
</tbody>
</table>
</div>

当前代码配置:

models.py

class Parameter(models.Model):
    text = models.CharField(blank=False, null=False, max_length=200)

class ParameterChoices(models.Model):
    text = models.CharField(blank=False, null=False, max_length=200)
    parameter = models.ForeignKey(Parameter, related_name='parameterchoices', on_delete=models.CASCADE, blank=False, null=False)

views.py

def parameters(request):
    params = Parameter.objects.all()
    param_choices = ParameterChoices.objects.all()
    context = {
        'parameters': params,
        'parameter_choices': param_choices,
    }
    return render(request, 'questionnaire/parameters.html', context)

解决方案

无需传递两个QuerySet,利用Django ORM的预取关联功能,优化视图与模板即可完成需求:

1. 优化视图:减少数据库查询次数

修改views.py,使用prefetch_related一次性获取所有参数及其关联的选项,避免N+1查询问题:

def parameters(request):
    # 预取每个Parameter对应的所有ParameterChoices
    params = Parameter.objects.prefetch_related('parameterchoices').all()
    context = {
        'parameters': params,
    }
    return render(request, 'questionnaire/parameters.html', context)

2. 编写HTML模板渲染表格

在parameters.html中,直接通过每个parameter对象的parameterchoices关联属性访问对应选项,循环渲染即可:

<div class="s-table-container">
  <table class="s-table">
    <thead>
      <tr>
        <th>参数</th>
        <th>可选选项</th>
      </tr>
    </thead>
    <tbody>
      {% for param in parameters %}
      <tr>
        <td>{{ param.text }}</td>
        <td>
          {% for choice in param.parameterchoices.all %}
            <code>{{ choice.text }}</code>
          {% endfor %}
        </td>
      </tr>
      {% empty %}
      <tr>
        <td colspan="2">暂无参数</td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</div>

补充说明

  • prefetch_related会执行两次查询(一次获取所有Parameter,一次获取所有关联的ParameterChoices),然后在内存中完成数据关联,比单独传递两个QuerySet更高效,也省去了模板中匹配参数与选项的额外逻辑。
  • 模板中param.parameterchoices.all的写法依赖模型中定义的related_name='parameterchoices',如果未定义该属性,默认写法为param.parameterchoices_set.all。

内容的提问来源于stack exchange,提问作者Trm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:13:33