Django 多注解返回错误结果

Posted

技术标签:

【中文标题】Django 多注解返回错误结果【英文标题】:Django multiple annotations returns wrong results 【发布时间】:2019-07-13 16:00:41 【问题描述】:

我正在尝试在 django 查询集中创建注释。注释是基于条件的反向外键计数。我遇到的问题是,当我使用条件对一个反向外键进行计数时,我得到了正确的数据,但是当我进行两个注释时,每个反向外键一个。

这是一个反向外键的带有 Count 注释的查询集:

ExamResponse.objects.filter(
        course_class__course=course,
        exam__exam_type=Exam.PRACTICE,
        user__is_demo=False,
        ended__isnull=False,
        id=125752
    ).order_by(
        'user_id',
        'started'
    ).annotate(
        total_ecq_count=Sum(
            Case(
                When(
                    choice_questions__response_time__gte=ENGAGEMENT_THRESHOLD,
                    choice_questions__id__isnull=False,
                    then=1
                ),
                default=0,
                output_field=IntegerField()
            ), 
            distinct=True
        ),
    ).values('total_ecq_count')

结果(正确结果):

<QuerySet ['total_ecq_count': 1]>

带有两个 Count 注释的查询

ExamResponse.objects.filter(
        course_class__course=course,
        exam__exam_type=Exam.PRACTICE,
        user__is_demo=False,
        ended__isnull=False,
        id=125752
    ).order_by(
        'user_id',
        'started'
    ).annotate(
        total_ecq_count=Sum(
            Case(
                When(
                    choice_questions__response_time__gte=ENGAGEMENT_THRESHOLD,
                    choice_questions__id__isnull=False,
                    then=1
                ),
                default=0,
                output_field=IntegerField()
            ), 
            distinct=True
        ),
        total_etq_count=Sum(
            Case(
                When(
                    text_questions__response_time__gte=ENGAGEMENT_THRESHOLD,
                    text_questions__id__isnull=False,
                    then=1
                ),
                default=0,
                output_field=IntegerField()
            ), 
            distinct=True
        ),
    ).values('total_ecq_count', 'total_etq_count')

结果:(total_ecq_count 从 1 变为 3!!!)

<QuerySet ['total_ecq_count': 3, 'total_etq_count': 4]>

【问题讨论】:

【参考方案1】:

我刚刚找到这篇文章,显然,这是一个已知错误,即两个不同外键的两个注释会创建重复计数。 https://code.djangoproject.com/ticket/25861

【讨论】:

以上是关于Django 多注解返回错误结果的主要内容,如果未能解决你的问题,请参考以下文章

石墨烯 django 继电器:继电器变换错误

逻辑或 Django 多对多查询返回重复结果

PL/SQL 函数返回错误结果

Django:Syncdb 错误地警告多对多字段已过时

在 JSON 中返回纯 Django 表单错误

Django开发之路 二(django的models表查询)