在 Django 中加入两个查询集
Posted
技术标签:
【中文标题】在 Django 中加入两个查询集【英文标题】:Joining two querysets in Django 【发布时间】:2016-08-16 06:01:36 【问题描述】:假设我有以下模型
class Award(models.Model):
user = models.ForeignKey(User)
class AwardReceived(models.Model):
award = models.ForeignKey(award)
date = models.DateField()
units = models.IntegerField()
class AwardUsed(models.Model):
award = models.ForeignKey(award)
date = models.DateField()
units = models.IntegerField()
现在,假设我想获得所有用户的奖励数量和所有用户使用的奖励数量(即包含两者的查询集)。我更喜欢为每个计算执行一个查询——当我将它结合到我的代码中时,我得到了一些意想不到的结果。此外,对于我的一些查询,不可能只进行一次查询,因为查询会变得太复杂 - 我正在计算 8 个字段。到目前为止,这就是我解决它的方法:
def get_summary(query_date)
summary = (Award.objects.filter(awardreceived__date__lte=query_date))
.annotate(awarded=Sum('awardissuedactivity__units_awarded')))
awards_used = (Award.objects.filter(awardused__date__lte=query_date)
.annotate(used=Sum('awardused__date__lte__units')))
award_used_dict =
for award in awards_used:
award_used_dict[award] = award.used
for award in summary:
award.used = award_used_dict.get(award, 0)
return summary
我确定必须有一种方法可以在没有字典方法的情况下解决这个问题?例如,像这样:awards_used.get(award=award)
,但这会导致每个循环都进行一次数据库查找。
或者其他一些奇特的方式来加入查询集?
请注意,这是一个简化的示例,我知道这个示例可以改进数据库结构,我只是想说明我的问题。
【问题讨论】:
你考试中的exercised_awards_dict
是什么?
对不起,我从我的代码中复制了,但没有更改所有变量名 - 现在修复它
【参考方案1】:
解决方案 1
尝试使用|
连接您的查询集
final_q = q1 | q2
在你的例子中
final_q = summary | awards_used
更新:
|使用计算属性不起作用,因此,我们可以先选择我们的查询集,然后映射我们的额外属性
summary = Award.objects.filter(awardreceived__date__lte=query_date)
awards_used = Award.objects.filter(awardused__date__lte=query_date)
final_q = summary | awards_used
final_q = final_q.annotate(used=Sum('awardused__date__lte__units')).annotate(awarded=Sum('awardissuedactivity__units_awarded'))
解决方案 2
使用chain内置函数
from itertools import chain
final_list = list(chain(summary, awards_used))
这种方法有一个问题,你不会得到一个查询集,你会得到一个包含实例的列表。
【讨论】:
如果我再使用 final_q[0].used 我得到一个属性错误。使用时好像不包括计算值| 非常感谢,我试试看。不要介意得到一个列表 订单是否保持? 重点不是合并查询集,而是加入它们对吗?以上是关于在 Django 中加入两个查询集的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio Report Services 中加入两个数据集