From 303e21121c75d84070cc442b1e410f7501a2cc18 Mon Sep 17 00:00:00 2001 From: Muhammad Anas Date: Fri, 27 Mar 2026 12:23:33 +0500 Subject: [PATCH 1/5] fix: set default value for pinned field on CommentThread to prevent NULL sort bug --- forum/backends/mysql/api.py | 1 + forum/backends/mysql/models.py | 4 +--- .../0005_alter_commentthread_pinned.py | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 forum/migrations/0005_alter_commentthread_pinned.py diff --git a/forum/backends/mysql/api.py b/forum/backends/mysql/api.py index b115119b..c383d31a 100644 --- a/forum/backends/mysql/api.py +++ b/forum/backends/mysql/api.py @@ -1865,6 +1865,7 @@ def create_thread(data: dict[str, Any]) -> str: thread_type=data.get("thread_type", "discussion"), context=data.get("context", "course"), last_activity_at=timezone.now(), + pinned=data.get("pinned", False), **optional_args, ) return str(new_thread.pk) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index 3924a0d6..ddc83134 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -238,9 +238,7 @@ class CommentThread(Content): max_length=50, choices=CONTEXT_CHOICES, default="course" ) closed: models.BooleanField[bool, bool] = models.BooleanField(default=False) - pinned: models.BooleanField[Optional[bool], bool] = models.BooleanField( - null=True, blank=True - ) + pinned: models.BooleanField[Optional[bool], bool] = models.BooleanField(default=False) last_activity_at: models.DateTimeField[Optional[datetime], datetime] = ( models.DateTimeField(null=True, blank=True) ) diff --git a/forum/migrations/0005_alter_commentthread_pinned.py b/forum/migrations/0005_alter_commentthread_pinned.py new file mode 100644 index 00000000..9eb8945e --- /dev/null +++ b/forum/migrations/0005_alter_commentthread_pinned.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.12 on 2026-03-27 06:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('forum', '0004_add_author_username_fields'), + ] + + operations = [ + migrations.AlterField( + model_name='commentthread', + name='pinned', + field=models.BooleanField(default=False), + ), + ] From edeeb83f3195e997e5638660fc047e9595643bf7 Mon Sep 17 00:00:00 2001 From: Muhammad Anas Date: Fri, 27 Mar 2026 13:01:45 +0500 Subject: [PATCH 2/5] chore: bumped version and updated changelog --- CHANGELOG.rst | 2 ++ forum/__init__.py | 2 +- tests/test_backends/test_mysql/test_models.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bd7b0897..39df10cb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,8 @@ Unreleased ********** * Add support for Typesense as the search backend. +* Fix: Set default value for ``pinned`` field on ``CommentThread`` to ``False`` + to prevent NULL sort bug. 0.3.4 – 2025-08-13 ****************** diff --git a/forum/__init__.py b/forum/__init__.py index bc1fa6c4..255a215f 100644 --- a/forum/__init__.py +++ b/forum/__init__.py @@ -2,4 +2,4 @@ Openedx forum app. """ -__version__ = "0.4.0" +__version__ = "0.4.1" diff --git a/tests/test_backends/test_mysql/test_models.py b/tests/test_backends/test_mysql/test_models.py index f483970e..6598c13a 100644 --- a/tests/test_backends/test_mysql/test_models.py +++ b/tests/test_backends/test_mysql/test_models.py @@ -106,7 +106,7 @@ def test_comment_thread_creation() -> None: assert comment_thread.thread_type == "discussion" assert comment_thread.context == "course" assert comment_thread.closed is False - assert comment_thread.pinned is None + assert comment_thread.pinned is False @pytest.mark.django_db From 2db7a64e7ef6bcf86bbba919d40353d6faf704a4 Mon Sep 17 00:00:00 2001 From: Muhammad Anas Date: Fri, 27 Mar 2026 14:38:40 +0500 Subject: [PATCH 3/5] test: fix test --- forum/backends/mysql/models.py | 4 +++- forum/migration_helpers.py | 2 +- forum/migrations/0005_alter_commentthread_pinned.py | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/forum/backends/mysql/models.py b/forum/backends/mysql/models.py index ddc83134..211d1ff5 100644 --- a/forum/backends/mysql/models.py +++ b/forum/backends/mysql/models.py @@ -238,7 +238,9 @@ class CommentThread(Content): max_length=50, choices=CONTEXT_CHOICES, default="course" ) closed: models.BooleanField[bool, bool] = models.BooleanField(default=False) - pinned: models.BooleanField[Optional[bool], bool] = models.BooleanField(default=False) + pinned: models.BooleanField[Optional[bool], bool] = models.BooleanField( + default=False + ) last_activity_at: models.DateTimeField[Optional[datetime], datetime] = ( models.DateTimeField(null=True, blank=True) ) diff --git a/forum/migration_helpers.py b/forum/migration_helpers.py index f47d5672..fb3a79a9 100644 --- a/forum/migration_helpers.py +++ b/forum/migration_helpers.py @@ -122,7 +122,7 @@ def create_or_update_thread(thread_data: dict[str, Any]) -> None: anonymous=thread_data.get("anonymous", False), anonymous_to_peers=thread_data.get("anonymous_to_peers", False), closed=thread_data.get("closed", False), - pinned=thread_data.get("pinned"), + pinned=thread_data.get("pinned", False), last_activity_at=make_aware(thread_data["last_activity_at"]), commentable_id=thread_data.get("commentable_id"), ) diff --git a/forum/migrations/0005_alter_commentthread_pinned.py b/forum/migrations/0005_alter_commentthread_pinned.py index 9eb8945e..68e9a7d4 100644 --- a/forum/migrations/0005_alter_commentthread_pinned.py +++ b/forum/migrations/0005_alter_commentthread_pinned.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('forum', '0004_add_author_username_fields'), + ("forum", "0004_add_author_username_fields"), ] operations = [ migrations.AlterField( - model_name='commentthread', - name='pinned', + model_name="commentthread", + name="pinned", field=models.BooleanField(default=False), ), ] From a668154f6e274b0ddc0834da0c29a9895ce50888 Mon Sep 17 00:00:00 2001 From: Muhammad Anas Date: Mon, 30 Mar 2026 15:17:30 +0500 Subject: [PATCH 4/5] fix: add backfill --- forum/migrations/0005_alter_commentthread_pinned.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/forum/migrations/0005_alter_commentthread_pinned.py b/forum/migrations/0005_alter_commentthread_pinned.py index 68e9a7d4..4b1cb80e 100644 --- a/forum/migrations/0005_alter_commentthread_pinned.py +++ b/forum/migrations/0005_alter_commentthread_pinned.py @@ -3,6 +3,11 @@ from django.db import migrations, models +def backfill_pinned_false(apps, schema_editor): + CommentThread = apps.get_model("forum", "CommentThread") + CommentThread.objects.filter(pinned__isnull=True).update(pinned=False) + + class Migration(migrations.Migration): dependencies = [ @@ -10,6 +15,7 @@ class Migration(migrations.Migration): ] operations = [ + migrations.RunPython(backfill_pinned_false, migrations.RunPython.noop), migrations.AlterField( model_name="commentthread", name="pinned", From bd9b8654b3cbaa01b068f28441fe83d4a190ddd9 Mon Sep 17 00:00:00 2001 From: Muhammad Anas Date: Mon, 30 Mar 2026 15:22:10 +0500 Subject: [PATCH 5/5] fix: type annotation issue --- forum/migrations/0005_alter_commentthread_pinned.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/forum/migrations/0005_alter_commentthread_pinned.py b/forum/migrations/0005_alter_commentthread_pinned.py index 4b1cb80e..c95ebcc6 100644 --- a/forum/migrations/0005_alter_commentthread_pinned.py +++ b/forum/migrations/0005_alter_commentthread_pinned.py @@ -1,9 +1,11 @@ # Generated by Django 5.2.12 on 2026-03-27 06:58 +from typing import Any + from django.db import migrations, models -def backfill_pinned_false(apps, schema_editor): +def backfill_pinned_false(apps: Any, schema_editor: Any) -> None: CommentThread = apps.get_model("forum", "CommentThread") CommentThread.objects.filter(pinned__isnull=True).update(pinned=False)