Skip to main content
 首页 » 编程设计

python之Django 计数过滤器注释不起作用

2024年09月07日40mq0036

我有两个模型“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”的“ child ”的数量以及类型为“2”的“ child ”的数量汇总到它,这就是我尝试这样做的方式:

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'.. 就像整个 'filter' 参数都被忽略了。

请您参考如下方法:

基于 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)) 

我希望它能帮助到其他人。