Skip to content

Commit 321a619

Browse files
fix: bug with some descendant counts
1 parent f5c8792 commit 321a619

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

openedx_tagging/core/tagging/models/base.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def _get_filtered_tags_one_level(
458458
qs = self.tag_set.filter(parent=None).annotate(depth=Value(0))
459459
qs = qs.annotate(parent_value=Value(None, output_field=models.CharField()))
460460
qs = qs.annotate(child_count=models.Count("children", distinct=True))
461-
qs = qs.annotate(grandchild_count=models.Count("children__children"))
461+
qs = qs.annotate(grandchild_count=models.Count("children__children", distinct=True))
462462
qs = qs.annotate(great_grandchild_count=models.Count("children__children__children"))
463463
qs = qs.annotate(descendant_count=F("child_count") + F("grandchild_count") + F("great_grandchild_count"))
464464
# Filter by search term:
@@ -520,7 +520,9 @@ def _get_filtered_tags_deep(
520520
qs = qs.filter(pk__in=matching_ids)
521521
qs = qs.annotate(
522522
child_count=models.Count("children", filter=Q(children__pk__in=matching_ids), distinct=True),
523-
grandchild_count=models.Count("children__children", filter=Q(children__children__pk__in=matching_ids)),
523+
grandchild_count=models.Count(
524+
"children__children", filter=Q(children__children__pk__in=matching_ids), distinct=True,
525+
),
524526
great_grandchild_count=models.Count(
525527
"children__children__children",
526528
filter=Q(children__children__children__pk__in=matching_ids),
@@ -534,7 +536,7 @@ def _get_filtered_tags_deep(
534536
# frontend.
535537
else:
536538
qs = qs.annotate(child_count=models.Count("children", distinct=True))
537-
qs = qs.annotate(grandchild_count=models.Count("children__children"))
539+
qs = qs.annotate(grandchild_count=models.Count("children__children", distinct=True))
538540
qs = qs.annotate(great_grandchild_count=models.Count("children__children__children"))
539541
qs = qs.annotate(descendant_count=F("child_count") + F("grandchild_count") + F("great_grandchild_count"))
540542

tests/openedx_tagging/core/tagging/test_models.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,37 @@ def test_tree_sort(self) -> None:
550550
" azure (ALPHABET) (children: 0)",
551551
]
552552

553+
def test_descendant_counts(self) -> None:
554+
"""
555+
Test getting the descendant count on a taxonomy known to cause aggregation
556+
bugs unless the aggregations are correctly specified with distinct=True
557+
558+
https://docs.djangoproject.com/en/5.0/topics/db/aggregation/#combining-multiple-aggregations
559+
"""
560+
taxonomy = api.create_taxonomy("ESDC Subset")
561+
api.add_tag_to_taxonomy(taxonomy, "Interests") # root tag
562+
api.add_tag_to_taxonomy(taxonomy, "Holland Codes", parent_tag_value="Interests") # child tag
563+
# Create the grandchild tag:
564+
g_tag = api.add_tag_to_taxonomy(taxonomy, "Interests - Holland Codes", parent_tag_value="Holland Codes")
565+
# Create the 6 great-grandchild tags:
566+
api.add_tag_to_taxonomy(taxonomy, "Artistic", parent_tag_value=g_tag.value)
567+
api.add_tag_to_taxonomy(taxonomy, "Conventional", parent_tag_value=g_tag.value)
568+
api.add_tag_to_taxonomy(taxonomy, "Enterprising", parent_tag_value=g_tag.value)
569+
api.add_tag_to_taxonomy(taxonomy, "Investigative", parent_tag_value=g_tag.value)
570+
api.add_tag_to_taxonomy(taxonomy, "Realistic", parent_tag_value=g_tag.value)
571+
api.add_tag_to_taxonomy(taxonomy, "Social", parent_tag_value=g_tag.value)
572+
573+
result = pretty_format_tags(taxonomy.get_filtered_tags(depth=1, include_counts=True))
574+
assert result == [
575+
"Interests (None) (used: 0, children: 1 + 7)", # 1 child + (1 grandchild and 6 great grandchild tags)
576+
]
577+
result2 = pretty_format_tags(taxonomy.get_filtered_tags(depth=None, include_counts=True))
578+
assert result2 == [
579+
"Interests (None) (used: 0, children: 1 + 7)",
580+
" Holland Codes (Interests) (used: 0, children: 1 + 6)",
581+
" Interests - Holland Codes (Holland Codes) (used: 0, children: 6)",
582+
]
583+
553584

554585
class TestFilteredTagsFreeTextTaxonomy(TestCase):
555586
"""

0 commit comments

Comments
 (0)