基于已有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
相关产品推荐
相关产品推荐

