【问题标题】:How to combine querysets retaining annotate fields?如何组合保留注释字段的查询集?
【发布时间】:2021-09-06 04:50:34
【问题描述】:

我对同一张表有两个不同的查询:

 m_i = MyModel.objects.filter(
            user__profile__newsletter=True
        ).annotate(name=F('user__profile__complete_name'))\
        .values('name')\
        .annotate(indicado=Count('user'))\
        .order_by('user__profile__complete_name')

m_e = MyModel.objects.filter(
            user__profile__newsletter=True,
            chosen=True)\
        ).annotate(name=F('user__profile__complete_name'))\
        .values('name')\
        .annotate(escolhido=Count('user'))\
        .order_by('user__profile__complete_name')  

除了第二个过滤器中的一个过滤器之外,查询非常相同,我为它们两个都注释了相同的值,但它们得出的值不同。现在查询集是这样的:

# m_i
[{name:'ex1', indicado: 1},
{name:'ex2', indicado: 2},
{name:'ex3', indicado: 9},
{name:'ex4', indicado: 3}]

# m_e
[{name:'ex1', escolhido: 1},
{name:'ex2', escolhido: 1},
{name:'ex3', escolhido: 4},
{name:'ex4', escolhido: 2}]

我想合并查询集,这样我就可以拥有这样的东西:

# union
[{name:'ex1', escolhido: 1, indicado: 1},
{name:'ex2', escolhido: 1, , indicado: 2},
{name:'ex3', escolhido: 4, , indicado: 9},
{name:'ex4', escolhido: 2, , indicado: 3}]

我尝试使用 union 这样的 m_i.union(m_e) 方法,但似乎它假定 indicadoescolhido 是同一件事,并且只保留两者之一。使用itertools.chain 一个接一个地返回给我两个查询集,而不是由同一个键联合起来。有没有办法在不迭代查询集的情况下合并它们?我可以遍历所有项目,因为它可以有数百行。

顺便说一句:我的数据库是 mysql 1.4 和 django 是 2.1 和不,遗憾的是我不能更新他们两个:(

【问题讨论】:

    标签: python mysql sql django orm


    【解决方案1】:

    为自己找到了解决方案。对于遇到与我相同的问题的任何人,这就是我现在所做的:

    md = MyModel.objects.
            ...
            .annotate(escolhido=Count('user', filter=Q(chosen=True)))\
            .annotate(indicado=Count('user'))\
    

    您可以只过滤aggregation function,而不是过滤整个查询集。

    【讨论】:

      猜你喜欢
      • 2018-01-17
      • 2022-12-06
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 2020-11-26
      • 2021-11-03
      • 2020-07-31
      相关资源
      最近更新 更多