我有3个链接的Django模型。
models.py
Assessment(models.Model):
finalized = models.BooleanField(default=False)
finalized_date = models.DateTimeField(default=blank, blank=True)
workstation = models.ForeignKey(Assessment, null=True, blank=True, on_delete=models.SET_NULL)
class Meta:
get_latest_by = "finalized_date"
Workstation(models.Model):
pass
Answer(models.Model):
score = models.IntegerField(default=0)
assessment = models.ForeignKey(Assessment, null=True, blank=True, on_delete=models.SET_NULL)
这是我的第一个问题:
我需要一个返回所有最新评估(L)的查询集。
例如,(L)是最新的:
Workstation 1 | Workstation 2 | Workstation 3
------------------------------------------------------
Assessment 1 (L) | Assessment 12 | Assessment 4
Assessment 2 | Assessment 41 | Assessment 15 (L)
Assessment 3 | Assessment 99 (L) | Assessment 9
因此查询集应返回:Assessment 1, Assessment 99 and Assessment 15
我考虑过做一个工作站的查询集,然后进行for
循环,但这样做成本太高,并产生了大量的查询。
第二个问题(与第一个问题相关):
我实际上需要一个与工作站最新评估相关的所有Answers的查询集。
我认为我可以将其分解为多个查询集以使其正常工作,但如果有办法从一个查询集中执行此操作,请教育我!
所以,一旦我从#1获得了Assessments的查询集,我就会使用follow querysets来获取我真正需要的内容。
final_queryset = Answer.objects.filter(assessment__in=QuerySet_From_Problem_1)
答案 0 :(得分:1)
第一个问题
首先,我认为你的Assessment -- Workstation
关系是倒置的。根据您的要求,Workstation
可以有多个Assessments
,因此模型应为:
Assessment(models.Model):
workstation = models.ForeignKey(Assessment, null=True,
blank=True, on_delete=models.SET_NULL)
finalized = models.BooleanField(default=False)
finalized_date = models.DateTimeField(default=blank, blank=True)
class Meta:
get_latest_by = "finalized_date"
Workstation(models.Model):
pass
现在,为了得到你想要的东西,你可以使用Django 1.11中引入的Subquery
feature:
from django.db.models import OuterRef, Subquery
latest = Assessment.objects.filter(
workstation=OuterRef('pk')).order_by('-finalized_date')
workstations = Workstation.objects.annotate(
latest_assessment_id=Subquery(latest.values('pk')[:1]))
for workstation in workstations:
print('Assessment {}'.format(workstation.latest_assessment_id))
第二个问题
现在您已经拥有评估ID,正如您所说,您只需得到答案:
latest_assessments_ids = (w.latest_assessment_id for w in workstations)
answers = Answer.objects.filter(assessment_id__in=latest_assessments_ids)