django - 使用 Exists、Subquery 和 OuterRef 优化 django 查询
问题描述
我需要帮助优化这个 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 -> 多对多到 UserEnrolment,module_progress -> 多对多到 CourseProgress,并且实例是序列化程序迭代中的当前 AssignmentModule。
我想在序列化程序中获取提交的用户数,所以我使用序列化程序方法字段。
要获得提交的用户数,我想检查 AssignmentModuleProgress 表中是否存在 module_progress = ModuleProgress.objects.get(module=instance, user=OuterRef('user')) 的条目用户是 UserEnrolments 表中的一个字段,用户应该在 user_enrolments 注释迭代中引用当前用户。我在过滤 is_submitted 的 True 条件后返回计数。
截至目前,我收到以下错误:
ValueError: This queryset contains a reference to an outer query and may only be used in a subquery.
解决方案
这可能是不使用子查询的解决方案:
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()
推荐阅读
- javascript - Fancybox + Flickity。iOS方向问题
- python - 错误:尝试打包 Python 项目时,包目录 'venv\Lib\site-packages\pip-10\0\1-py3\6\egg\pip'
- c - 需要帮助调试段错误
- python - 将列转换为标题行
- javascript - JQuery InArray 无法正常工作?
- .htaccess - 将域和子域都重定向到 .htaccess 中的 https
- flutter - 调整颤振 AppBar 中的前导小部件的大小
- selenium - PayPal Sandbox 找不到密码字段
- javascript - TypeError:无法使用 AngularJS 读取未定义的属性“推送”
- reactjs - 反应导航 tabBarOnPress