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] 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")