Skip to content

Commit

Permalink
Optimize topics hierarchy helper (#6404)
Browse files Browse the repository at this point in the history
* Optimize topics hieararchy helper

* adjust get_hierarchical_topics() for product caching

---------

Co-authored-by: Ryan Johnson <[email protected]>
  • Loading branch information
akatsoulas and escattone authored Dec 10, 2024
1 parent a73536d commit 7303cd6
Showing 1 changed file with 38 additions and 8 deletions.
46 changes: 38 additions & 8 deletions kitsune/flagit/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.utils import timezone
Expand Down Expand Up @@ -120,13 +121,43 @@ def flagged_queue(request):
)


def get_hierarchical_topics(topics, parent=None, level=0):
"""Recursively build hierarchical topics."""
def get_hierarchical_topics(product, cache_timeout=3600):
"""
Build hierarchical topics filtered by the given product.
Args:
product: The product that should be used to filter the topics.
cache_timeout: The number of seconds to cache the result for the
given product. Defaults to 1 hour.
Returns:
A list of dictionaries representing the hierarchical structure of topics.
"""
cache_key = f"hierarchical_topics_{product.slug}"
if cached_topics := cache.get(cache_key):
return cached_topics

topics = list(
Topic.active.filter(products=product).order_by("title").values("id", "title", "parent_id")
)
topic_dict = {}
for topic in topics:
parent_id = topic["parent_id"]
if parent_id not in topic_dict:
topic_dict[parent_id] = []
topic_dict[parent_id].append(topic)

hierarchical = []
for topic in topics.filter(parent=parent).order_by("title"):
spaces = "&nbsp;" * (level * 4)
hierarchical.append({"id": topic.id, "title": f"{spaces}{topic.title}"})
hierarchical.extend(get_hierarchical_topics(topics, parent=topic, level=level + 1))

def build_hierarchy(parent_id=None, level=0):
children = topic_dict.get(parent_id, [])
for child in children:
spaces = "&nbsp;" * (level * 4)
hierarchical.append({"id": child["id"], "title": f"{spaces}{child['title']}"})
build_hierarchy(child["id"], level + 1)

build_hierarchy()
cache.set(cache_key, hierarchical, cache_timeout)
return hierarchical


Expand All @@ -152,8 +183,7 @@ def moderate_content(request):

for obj in objects:
question = obj.content_object
all_topics = Topic.active.filter(is_archived=False, products=question.product)
obj.available_topics = get_hierarchical_topics(all_topics)
obj.available_topics = get_hierarchical_topics(question.product)
obj.available_tags = available_tags
obj.saved_tags = question.tags.values_list("id", flat=True)
return render(
Expand Down

0 comments on commit 7303cd6

Please sign in to comment.