From b1539853b294e7afa13bf5f0b4436a98ced48a6a Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 09:54:22 +0000 Subject: [PATCH 1/2] feat: add is_scheduled column to submission admin Add a new column in the submission admin that shows whether a submission is scheduled in the conference. The column displays a boolean checkmark using Django's admin.display decorator with boolean=True. - Add `is_scheduled` to list_display in SubmissionAdmin - Implement `is_scheduled` method that checks if submission has schedule items - Optimize queryset with prefetch_related for schedule_items to avoid N+1 - Add tests for the new is_scheduled method Closes #4585 Co-authored-by: Marco Acierno --- backend/submissions/admin.py | 12 +++++++++++- backend/submissions/tests/test_admin.py | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/backend/submissions/admin.py b/backend/submissions/admin.py index 5e6773820c..6c208f896e 100644 --- a/backend/submissions/admin.py +++ b/backend/submissions/admin.py @@ -222,6 +222,7 @@ class SubmissionAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin): "speaker_display_name", "type", "status", + "is_scheduled", "conference", "open_submission", "inline_tags", @@ -306,6 +307,15 @@ def speaker_display_name(self, obj): def inline_tags(self, obj): return ", ".join([tag.name for tag in obj.tags.all()]) + @admin.display( + description="Scheduled", + boolean=True, + ) + def is_scheduled(self, obj): + # Use bool() on all() to utilize prefetch_related data instead of exists() + # which would issue an additional query + return bool(obj.schedule_items.all()) + @admin.display( description="Open", ) @@ -318,7 +328,7 @@ def open_submission(self, obj): # pragma: no cover ) def get_queryset(self, request): - return super().get_queryset(request).prefetch_related("tags") + return super().get_queryset(request).prefetch_related("tags", "schedule_items") class Media: js = ["admin/js/jquery.init.js"] diff --git a/backend/submissions/tests/test_admin.py b/backend/submissions/tests/test_admin.py index 12f8577a04..15b70102ab 100644 --- a/backend/submissions/tests/test_admin.py +++ b/backend/submissions/tests/test_admin.py @@ -3,7 +3,9 @@ from notifications.tests.factories import EmailTemplateFactory from notifications.models import EmailTemplateIdentifier, SentEmail import pytest +from schedule.tests.factories import ScheduleItemFactory from submissions.admin import ( + SubmissionAdmin, apply_and_notify_status_change, send_proposal_in_waiting_list_email_action, send_proposal_rejected_email_action, @@ -14,6 +16,25 @@ pytestmark = pytest.mark.django_db +def test_is_scheduled_returns_true_when_submission_has_schedule_items(): + submission = SubmissionFactory() + ScheduleItemFactory( + submission=submission, + conference=submission.conference, + type="submission", + ) + + admin = SubmissionAdmin(model=Submission, admin_site=None) + assert admin.is_scheduled(submission) is True + + +def test_is_scheduled_returns_false_when_submission_has_no_schedule_items(): + submission = SubmissionFactory() + + admin = SubmissionAdmin(model=Submission, admin_site=None) + assert admin.is_scheduled(submission) is False + + def test_send_proposal_rejected_email_action(rf, mocker): mock_task = mocker.patch("submissions.admin.send_proposal_rejected_email") mocker.patch("submissions.admin.messages") From 8c29757c5578835b9e35c3dc95d888f97f283c4a Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 09:03:06 +0000 Subject: [PATCH 2/2] feat: show scheduled datetime in submission admin instead of boolean Update the is_scheduled column to display the actual scheduled datetime(s) instead of just a boolean checkmark. This makes it easier for admins to see when a submission is scheduled without having to open the schedule. Co-authored-by: Marco Acierno Co-Authored-By: Claude Opus 4.5 --- backend/submissions/admin.py | 13 ++++++++----- backend/submissions/tests/test_admin.py | 11 ++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/backend/submissions/admin.py b/backend/submissions/admin.py index 6c208f896e..8030b95354 100644 --- a/backend/submissions/admin.py +++ b/backend/submissions/admin.py @@ -309,12 +309,13 @@ def inline_tags(self, obj): @admin.display( description="Scheduled", - boolean=True, ) def is_scheduled(self, obj): - # Use bool() on all() to utilize prefetch_related data instead of exists() - # which would issue an additional query - return bool(obj.schedule_items.all()) + schedule_items = obj.schedule_items.all() + if not schedule_items: + return "-" + times = [item.start.strftime("%Y-%m-%d %H:%M") for item in schedule_items] + return ", ".join(times) @admin.display( description="Open", @@ -328,7 +329,9 @@ def open_submission(self, obj): # pragma: no cover ) def get_queryset(self, request): - return super().get_queryset(request).prefetch_related("tags", "schedule_items") + return super().get_queryset(request).prefetch_related( + "tags", "schedule_items__slot__day" + ) class Media: js = ["admin/js/jquery.init.js"] diff --git a/backend/submissions/tests/test_admin.py b/backend/submissions/tests/test_admin.py index 15b70102ab..bb7af3f5dc 100644 --- a/backend/submissions/tests/test_admin.py +++ b/backend/submissions/tests/test_admin.py @@ -16,23 +16,24 @@ pytestmark = pytest.mark.django_db -def test_is_scheduled_returns_true_when_submission_has_schedule_items(): +def test_is_scheduled_returns_datetime_when_submission_has_schedule_items(): submission = SubmissionFactory() - ScheduleItemFactory( + schedule_item = ScheduleItemFactory( submission=submission, conference=submission.conference, type="submission", ) admin = SubmissionAdmin(model=Submission, admin_site=None) - assert admin.is_scheduled(submission) is True + expected_time = schedule_item.start.strftime("%Y-%m-%d %H:%M") + assert admin.is_scheduled(submission) == expected_time -def test_is_scheduled_returns_false_when_submission_has_no_schedule_items(): +def test_is_scheduled_returns_dash_when_submission_has_no_schedule_items(): submission = SubmissionFactory() admin = SubmissionAdmin(model=Submission, admin_site=None) - assert admin.is_scheduled(submission) is False + assert admin.is_scheduled(submission) == "-" def test_send_proposal_rejected_email_action(rf, mocker):