From 8e4fbe42a19816df363e6340904e18d473510597 Mon Sep 17 00:00:00 2001 From: Naincy Chourasia Date: Tue, 30 Jun 2026 07:44:13 +0000 Subject: [PATCH 1/6] fix: inconsistent loading of discussion thread response --- forum/backends/mysql/models.py | 41 ++++++++++++++-------------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index 806b4292..39469dfb 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -437,40 +437,33 @@ def get_sort_key(self) -> str: def get_list(**kwargs: Any) -> list[dict[str, Any]]: """ Retrieves a list of all comments in the database based on provided filters. - - Args: - kwargs: The filter arguments. - - Returns: - A list of comments. + Optimized with select_related and DB-level sorting/pagination. """ + from django.db.models import F + sort = kwargs.pop("sort", None) resp_skip = kwargs.pop("resp_skip", 0) resp_limit = kwargs.pop("resp_limit", None) - comments = Comment.objects.filter(**kwargs) - result = [] + + # select_related eliminates FK queries in to_dict() + comments = Comment.objects.filter(**kwargs).select_related( + 'author', 'parent', 'comment_thread', 'deleted_by' + ) + + # DB-level sorting instead of Python sorted() if sort: if sort == 1: - result = sorted( - comments, key=lambda x: (x.sort_key is None, x.sort_key or "") - ) + comments = comments.order_by(F('sort_key').asc(nulls_last=True)) elif sort == -1: - result = sorted( - comments, - key=lambda x: (x.sort_key is None, x.sort_key or ""), - reverse=True, - ) - - paginated_comments = result or list(comments) + comments = comments.order_by(F('sort_key').desc(nulls_last=True)) - # Apply pagination if resp_limit is provided + # DB-level pagination instead of loading all then slicing if resp_limit is not None: - resp_end = resp_skip + resp_limit - paginated_comments = result[resp_skip:resp_end] - elif resp_skip: # If resp_limit is None but resp_skip is provided - paginated_comments = result[resp_skip:] + comments = comments[resp_skip:resp_skip + resp_limit] + elif resp_skip: + comments = comments[resp_skip:] - return [content.to_dict() for content in paginated_comments] + return [content.to_dict() for content in comments] @staticmethod def get_list_total_count(**kwargs: Any) -> int: From 3ce1bc833d267fb30b2b3d7516b0e9c52d61dae7 Mon Sep 17 00:00:00 2001 From: Naincy Chourasia Date: Tue, 30 Jun 2026 07:56:06 +0000 Subject: [PATCH 2/6] fix: inconsistent loading of discussion thread response --- forum/backends/mysql/models.py | 2 +- forum/serializers/comment.py | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index 39469dfb..272d96f4 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -11,6 +11,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError +from django.db.models import F from django.db import models from django.db.models import QuerySet from django.utils import timezone @@ -439,7 +440,6 @@ def get_list(**kwargs: Any) -> list[dict[str, Any]]: Retrieves a list of all comments in the database based on provided filters. Optimized with select_related and DB-level sorting/pagination. """ - from django.db.models import F sort = kwargs.pop("sort", None) resp_skip = kwargs.pop("resp_skip", 0) diff --git a/forum/serializers/comment.py b/forum/serializers/comment.py index 4c68b0f1..3fb4c8d4 100644 --- a/forum/serializers/comment.py +++ b/forum/serializers/comment.py @@ -86,21 +86,11 @@ def get_children(self, obj: Any) -> list[dict[str, Any]]: return list(serializer.data) def to_representation(self, instance: Any) -> dict[str, Any]: + """Return comment representation.""" comment = super().to_representation(instance) comment.pop("historical_abuse_flaggers") if comment["parent_id"] == "None": comment["parent_id"] = None - - thread = self.backend.get_thread(comment["thread_id"]) - comment_from_db = self.backend.get_comment(comment["id"]) - if ( - not comment["endorsed"] - and comment_from_db - and "endorsement" not in comment_from_db - and thread - and thread["thread_type"] == "question" - ): - comment.pop("endorsement", None) return comment def create(self, validated_data: dict[str, Any]) -> Any: From cb1b54fbc0736df5711a2dc7fb9704a9697ba0ab Mon Sep 17 00:00:00 2001 From: Naincy Chourasia Date: Tue, 30 Jun 2026 08:00:14 +0000 Subject: [PATCH 3/6] fix: inconsistent loading of discussion thread response --- forum/backends/mysql/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index 272d96f4..68553c8e 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -447,19 +447,19 @@ def get_list(**kwargs: Any) -> list[dict[str, Any]]: # select_related eliminates FK queries in to_dict() comments = Comment.objects.filter(**kwargs).select_related( - 'author', 'parent', 'comment_thread', 'deleted_by' + "author", "parent", "comment_thread", "deleted_by" ) # DB-level sorting instead of Python sorted() if sort: if sort == 1: - comments = comments.order_by(F('sort_key').asc(nulls_last=True)) + comments = comments.order_by(F("sort_key").asc(nulls_last=True)) elif sort == -1: - comments = comments.order_by(F('sort_key').desc(nulls_last=True)) + comments = comments.order_by(F("sort_key").desc(nulls_last=True)) # DB-level pagination instead of loading all then slicing if resp_limit is not None: - comments = comments[resp_skip:resp_skip + resp_limit] + comments = comments[resp_skip : resp_skip + resp_limit] elif resp_skip: comments = comments[resp_skip:] From af04921d0e2ba55f088e786abda27a1cdfc6cf5e Mon Sep 17 00:00:00 2001 From: Naincy Chourasia Date: Tue, 30 Jun 2026 08:04:42 +0000 Subject: [PATCH 4/6] fix: inconsistent loading of discussion thread response --- forum/backends/mysql/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index 68553c8e..422d6bb5 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -459,7 +459,7 @@ def get_list(**kwargs: Any) -> list[dict[str, Any]]: # DB-level pagination instead of loading all then slicing if resp_limit is not None: - comments = comments[resp_skip : resp_skip + resp_limit] + comments = comments[resp_skip: resp_skip + resp_limit] elif resp_skip: comments = comments[resp_skip:] From 3ac44fb8a8f0add96516bed7e12997b6a617ffa8 Mon Sep 17 00:00:00 2001 From: Naincy Chourasia Date: Tue, 30 Jun 2026 08:36:49 +0000 Subject: [PATCH 5/6] fix: inconsistent loading of discussion thread response --- forum/backends/mysql/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index 422d6bb5..68553c8e 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -459,7 +459,7 @@ def get_list(**kwargs: Any) -> list[dict[str, Any]]: # DB-level pagination instead of loading all then slicing if resp_limit is not None: - comments = comments[resp_skip: resp_skip + resp_limit] + comments = comments[resp_skip : resp_skip + resp_limit] elif resp_skip: comments = comments[resp_skip:] From 4a006feaf238e0992e34dae51863d23b7611737f Mon Sep 17 00:00:00 2001 From: Naincy Chourasia Date: Tue, 30 Jun 2026 08:47:26 +0000 Subject: [PATCH 6/6] fix: inconsistent loading of discussion thread response --- forum/backends/mysql/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index 68553c8e..565d1de3 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -459,7 +459,8 @@ def get_list(**kwargs: Any) -> list[dict[str, Any]]: # DB-level pagination instead of loading all then slicing if resp_limit is not None: - comments = comments[resp_skip : resp_skip + resp_limit] + resp_end = resp_skip + resp_limit + comments = comments[resp_skip:resp_end] elif resp_skip: comments = comments[resp_skip:]