【问题标题】:Joining two querysets in Django在 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是什么?
  • 对不起,我从我的代码中复制了,但没有更改所有变量名 - 现在修复它

标签: python django


【解决方案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 我得到一个属性错误。使用时好像不包括计算值|
  • 非常感谢,我试试看。不要介意得到一个列表
  • 订单是否保持?
  • 重点不是合并查询集,而是加入它们对吗?
猜你喜欢
  • 2015-10-26
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
  • 2021-11-15
  • 2012-03-28
  • 2020-11-24
相关资源
最近更新 更多