如何使用更新合并两个查询的结果

时间:2019-01-17 14:38:11

标签: python django

我必须显示类别的名称和每个类别中的项目数量。 这些项目可以更改类别,因此我将这些项目的历史记录保存在表items_history

要显示所有类别名称,我正在运行此查询:

category_total = Category.objects.all()

结果示例:

<QuerySet [<Category: Drink>, <Category: Food>, <Category: Fun>, <Category: Suplies>]>

要获取每个类别中的商品数量,我必须检入表items_history

items_history = Category.objects.filter(items_history__current=1).annotate(qtd=Count("items_history__idea_id"))

结果示例:

<QuerySet [<Category: Food>]> 
 items_history[0].name -> 'Food'
 items_history[0].qtd -> 5

在这种情况下,我只有食品类别中的项目。所以我不能只在items_history中进行一个查询,因为我不会得到其他类别中的项目数量(在这种情况下为0)。

我需要获取所有类别及其各自的数量,因此,如果某个类别未在items_history中保留,则应该获取类别namequantity = 0。 预期结果:

        items_history[0].name -> 'Drink'
        items_history[0].qtd -> 0

        items_history[1].name -> 'Food'
        items_history[1].qtd -> 5

        items_history[1].name -> 'Fun'
        items_history[1].qtd -> 0

        items_history[1].name -> 'Suplies'
        items_history[1].qtd -> 0

我正在尝试使用update像这样合并category_totalitems_history的结果:

 category_total.update(items_history);

但是它不起作用。我怎样才能做到这一点?如果不可能,您是否还有其他想法来合并这些查询的结果?

我的模特:

 class Category(models.Model):
        name = models.CharField(max_length=50)
        description = models.TextField(max_length=500, blank=True,  null=True)
        order = models.PositiveSmallIntegerField(default=False)

        def __str__(self):
            return self.name



    class Items_History(models.Model):  # noqa   
        current_phase = models.ForeignKey('Category', on_delete=models.DO_NOTHING)
        previous_phase = models.PositiveSmallIntegerField()
        date_change = models.DateTimeField('data da mudança')
        idea = models.ForeignKey('Idea', on_delete=models.DO_NOTHING)
        author = models.ForeignKey('users.UserProfile', on_delete=models.DO_NOTHING)
        current = models.BooleanField()

1 个答案:

答案 0 :(得分:3)

开始,我们可以在Count function [Django-doc]中使用filter参数。

因此,这使我们可以编写如下查询:

from django.db.models import Count, Q

Category.objects.annotate(
    qtd=Count("items_history__idea_id", filter=Q(items_history__current=1))
)

因此,这会将过滤移至COUNT(..)部分本身,例如:

SELECT category.*, 
       COUNT(CASE WHEN items_history.current
                THEN items_history.idea_id
                ELSE NULL END) AS qtd
FROM category
LEFT OUTER JOIN items_history ON category.id = items_history.current_phase_id
GROUP BY category.id

如果相同 Item相同 Category,则{{1 }}设置为Item_History,您可能还想为其添加current标志:

True