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

基于已有QuerySet过滤Django QuerySet的实现方法问询

一步到位获取评估关联的所有问题(优化Django查询)

嘿,我懂你找了好几天没搞定的郁闷——其实不用分两次查询再传ID,咱们可以利用Django的关联查询直接把需要的数据一次性拉出来,既简洁又高效!

先理清楚模型关联逻辑(假设你的模型结构大概是这样)

首先得确认你的模型之间的关联关系,比如:

from django.db import models
from django.contrib.auth.models import User

class Assessment(models.Model):
    title = models.CharField(max_length=200)
    # 其他评估相关字段

class Question(models.Model):
    assessment = models.ForeignKey(
        Assessment, 
        on_delete=models.CASCADE, 
        related_name='questions'  # 这个反向关联名很重要,用来从评估找问题
    )
    content = models.TextField()
    # 其他问题相关字段

class AssessmentResponse(models.Model):
    assessment = models.ForeignKey(Assessment, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    # 其他响应相关字段

优化后的查询方式

不用先查ResponseDetails再提取assessment_id,直接通过关联查询+预取拿到所有需要的数据:

# 获取指定response_id的响应,同时预取关联的评估,以及评估下的所有问题
response_with_questions = AssessmentResponse.objects.select_related('assessment').prefetch_related('assessment__questions').get(id=response_id)
  • select_related('assessment'):因为AssessmentResponse和Assessment是一对一外键关联,用这个可以一次性把关联的评估数据拉出来,避免N+1查询。
  • prefetch_related('assessment__questions'):针对Assessment和Question的反向外键关联(多对一),预取该评估下的所有问题,同样减少查询次数。

模板里直接使用

拿到数据后,在模板里直接遍历关联的问题就行,不用额外处理:

<!-- 展示评估信息 -->
<h3>{{ response_with_questions.assessment.title }}</h3>

<!-- 遍历所有关联的问题 -->
{% for question in response_with_questions.assessment.questions %}
    <div class="question-item">
        <p>{{ forloop.counter }}. {{ question.content }}</p>
        <!-- 这里可以添加问题的其他字段,比如选项、分值等 -->
    </div>
{% endfor %}

注意事项

如果你的模型里Question的外键没有设置related_name,Django默认的反向关联名是question_set,那模板里就要改成response_with_questions.assessment.question_set.all。

这样是不是比原来的方法简洁多了?而且查询效率也更高,不会出现多次数据库请求的问题~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:26:59