Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 31 additions & 17 deletions contentcuration/contentcuration/viewsets/channel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import logging
import uuid
from functools import reduce
from operator import or_
from typing import Dict
Expand All @@ -9,13 +8,10 @@
from django.conf import settings
from django.db import IntegrityError
from django.db.models import Exists
from django.db.models import F
from django.db.models import OuterRef
from django.db.models import Q
from django.db.models import Subquery
from django.db.models import UUIDField
from django.db.models import Value
from django.db.models.functions import Cast
from django.db.models.functions import Coalesce
from django.http import HttpResponse
from django.http import HttpResponseNotFound
Expand All @@ -25,7 +21,6 @@
from django_cte import With
from django_filters.rest_framework import BooleanFilter
from django_filters.rest_framework import CharFilter
from kolibri_public.models import ContentNode as PublicContentNode
from le_utils.constants import content_kinds
from le_utils.constants import roles
from rest_framework import serializers
Expand Down Expand Up @@ -744,20 +739,39 @@ def _get_channel_content_languages(self, channel_id, main_tree_id=None) -> List[
if not channel_id:
return []

# determine the tree_id for the channel or from the root node (main_tree_id)
tree_id = None
if main_tree_id:
tree_id = (
ContentNode.objects.filter(id=main_tree_id)
.values_list("tree_id", flat=True)
.first()
)
elif not main_tree_id:
try:
tree_id = (
Channel.objects.filter(pk=channel_id)
.values_list("main_tree__tree_id", flat=True)
.first()
)
except Exception as e:
logging.error(str(e))
return []

try:
ids_to_exclude = [main_tree_id] if main_tree_id else []
node_ids_subquery = PublicContentNode.objects.filter(
channel_id=uuid.UUID(channel_id),
).values_list("id", flat=True)
lang_ids = ContentNode.objects.filter(
# performance: use a CTE to select just the tree's nodes, without default MPTT ordering,
# then filter against the CTE to get the distinct language IDs
cte = With(
ContentNode.objects.filter(tree_id=tree_id)
.values("id", "language_id")
.order_by()
)
qs = cte.queryset().with_cte(cte).filter(
language_id__isnull=False
).annotate(
cast_node_id=Cast(F('node_id'), output_field=UUIDField())
).filter(
cast_node_id__in=Subquery(node_ids_subquery)
).exclude(
id__in=ids_to_exclude
).values_list('language_id', flat=True).distinct()
)
if main_tree_id:
qs = qs.exclude(id=main_tree_id)
lang_ids = qs.values_list('language_id', flat=True).distinct()
unique_lang_ids = list(set(lang_ids))
except Exception as e:
logging.error(str(e))
Expand Down