使用现有,子查询和OuterRef优化Django查询

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

我需要帮助来优化此django查询。代码和用例如下:

我的代码:

  user_enrolments = UserEnrolment.objects.filter(
            enrolment__enrollable__id__in=course_ids_taught_by_teacher,
            course_progresses__module_progresses__module=instance).only("id").annotate(
            submitted_attempt=Exists(
                AssignmentModuleProgress.objects
                .annotate(user=OuterRef('id'))
                .filter(
                    module_progress=Subquery(
                    ModuleProgress.objects.get(module=instance, user=OuterRef('user'))),
                    is_submitted=True)
            ))
        return user_enrolments.filter(submitted_attempt=True).count()

course_progresses->多对多用户注册,module_progress-> CourseProgress和实例是序列化程序迭代中的当前AssignmentModule。

我想在序列化器中获取提交的用户数,所以我使用序列化器方法字段。

要获取提交的用户数,我想检查是否在Module_progress = ModuleProgress.objects.get(module = instance,user = OuterRef('user'))的AssignmentModuleProgress表中存在条目用户是UserEnrolments表中的一个字段,用户应在user_enrolments批注迭代中引用当前用户。我在过滤is_submitted的True条件后返回了计数。

截至目前,我收到以下错误:

ValueError: This queryset contains a reference to an outer query and may only be used in a subquery.
django django-models django-rest-framework django-queryset
1个回答
0
投票

这可能是不使用子查询的解决方案:

  user_enrolments = UserEnrolment.objects.filter(
            enrolment__enrollable__id__in=course_ids_taught_by_teacher,
            course_progresses__module_progresses__module=instance).only("id").annotate(
            submitted_attempt=Exists(
                AssignmentModuleProgress.objects
                .annotate(user=OuterRef('pk'))
                .filter(
                    Q(module_progress__module=instance) &
                    Q(module_progress__user=OuterRef('user')),
                    is_submitted=True)
            ))
        return user_enrolments.filter(submitted_attempt=True).count()
© www.soinside.com 2019 - 2024. All rights reserved.