在 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 中加入两个查询集的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django 在查询中加入 3 个表

在 Visual Studio Report Services 中加入两个数据集

在 MS ACCESS 中加入两个不同的计数查询

如何在 JPA JPQL 查询中加入两个实体集合?

有没有办法在 SQL 中加入两个查询,每个查询都有一个 order by?

如何在 App Script 中加入两个表并将数据提取到大查询现有表中