Django Count过滤注释不起作用

问题描述 投票:0回答:1

我有两个模型'ModelParent'和'ModelChild',其中'ModelParent'有很多'ModelChild',这里是我的模型结构:

class ModelParent(models.Model):
    ... some params ...


class ModelChild(models.Model):
    TYPES = (
        (1, 'First'),
        (2, 'Second'),
    )
    parent = models.ForeignKey(ModelParent, on_delete=models.CASCADE, related_name='childs')
    type = models.SmallIntegerField(choices=TYPES, default=0)

目前,数据库中只有一个'ModelChild'属于当前数据库中唯一的'ModelParent','ModelChild'的'type'值等于'1',我得到'ModelParent'对象我需要将其类型为“1”的“孩子”的数量以及类型为“2”的“孩子”的数量汇总到它,这是我尝试这样做的方式:

queryset = ModelParent.objects \
        .annotate(first_count=Count('childs', filter=Q(childs__type=1))) \
        .annotate(second_count=Count('childs', filter=Q(childs__type=2))).get(pk=1)

查询不会抛出任何错误,但在查看响应时,两个注释的值均为“1”,而“first_count”的值应为“1”,“second_count”的值应为“0”。

我也注意到,无论我在过滤器“filter = Q(childs__type = 1)”中设置为'childs__type'的值是什么,结果总是相同的,我可以这样设置它,例如:'childs _type = 10'并且计数仍然等于'1'。就像整个'过滤器'参数被忽略一样。

python django django-models
1个回答
1
投票

基于this answer我设法以这种方式实现它,但我需要在子查询中添加一些像'output_field'这样的东西,为注释添加'Coalesce',django需要'output_field',没有它就不行,'Coalesce'是必需的,因为如果结果为零,默认情况下子查询将返回'null',因此'Coalesce'的作用是每当结果为null时检索默认值,我在此设置为零案件:

    childs_base_query = ModelChild.objects.filter(parent=OuterRef('pk'))
    first_type_query = Subquery(childs_base_query
                           .filter(type=1)
                           .values('parent')
                           .annotate(count=Count('pk'))
                           .values('count')
                           , output_field=IntegerField())

    second_type_query = Subquery(childs_base_query
                              .filter(type=2)
                              .values('parent')
                              .annotate(count=Count('pk'))
                              .values('count')
                              , output_field=IntegerField())

    queryset = ModelParent.objects \
        .annotate(first_count=Coalesce(first_type_query, 0)) \
        .annotate(second_count=Coalesce(second_type_query, 0))

我希望它可以帮助别人。

© www.soinside.com 2019 - 2024. All rights reserved.