Optimize competences queries

This commit is contained in:
Christian Cueni 2024-07-22 11:49:55 +02:00
parent 2d3234c7ce
commit 128c8da2e6
1 changed files with 27 additions and 23 deletions

View File

@ -1,10 +1,13 @@
from typing import List, Tuple
import graphene
import structlog
from wagtail.models import Page
from vbv_lernwelt.course.models import CourseCompletion, CourseCompletionStatus
logger = structlog.get_logger(__name__)
class CompetencePerformanceStatisticsSummaryType(graphene.ObjectType):
_id = graphene.ID(required=True)
@ -41,25 +44,23 @@ def competences(
completions = CourseCompletion.objects.filter(
course_session_id__in=course_session_selection_ids,
page_type="competence.PerformanceCriteria",
).prefetch_related("course_session", "page")
).select_related("course_session", "page")
if user_selection_ids is not None:
completions = completions.filter(user_id__in=user_selection_ids)
competence_records = {}
page_ids = completions.values_list("page_id", flat=True).distinct()
pages = Page.objects.filter(id__in=page_ids)
learning_units = {page.id: page.specific.learning_unit for page in pages}
unique_page_ids = {completion.page.id for completion in completions}
learning_units = {
page_id: Page.objects.get(id=page_id).specific.learning_unit
for page_id in unique_page_ids
}
circles = {
lu.id: c
for lu in learning_units.values()
if (lu is not None and (c := lu.get_circle()) is not None)
and (circle_ids is None or c.id in circle_ids)
if lu and (c := lu.get_circle()) and (circle_ids is None or c.id in circle_ids)
}
competence_records = {}
for completion in completions:
learning_unit = learning_units.get(completion.page.id)
@ -73,20 +74,23 @@ def competences(
combined_id = f"{circle.id}-{completion.course_session.id}@{urql_id_postfix}"
competence_records.setdefault(combined_id, {}).setdefault(
learning_unit,
CompetenceRecordStatisticsType(
_id=combined_id, # noqa
title=learning_unit.title, # noqa
course_session_id=completion.course_session.id, # noqa
generation=completion.course_session.generation, # noqa
circle_id=circle.id, # noqa
success_count=0, # noqa
fail_count=0, # noqa
if combined_id not in competence_records:
competence_records[combined_id] = {}
if learning_unit not in competence_records[combined_id]:
competence_records[combined_id][
learning_unit
] = CompetenceRecordStatisticsType(
_id=combined_id,
title=learning_unit.title,
course_session_id=completion.course_session.id,
generation=completion.course_session.generation,
circle_id=circle.id,
success_count=0,
fail_count=0,
details_url=f"/course/{course_slug}/cockpit?courseSessionId={completion.course_session.id}",
# noqa
),
)
)
if completion.completion_status == CourseCompletionStatus.SUCCESS.value:
competence_records[combined_id][learning_unit].success_count += 1
@ -99,7 +103,7 @@ def competences(
for record in circle_records.values()
]
success_count = sum([c.success_count for c in values])
fail_count = sum([c.fail_count for c in values])
success_count = sum(c.success_count for c in values)
fail_count = sum(c.fail_count for c in values)
return values, success_count, fail_count