Skip to content

Fix crash in Django admin when ScheduleItem has None speakers#4658

Merged
marcoacierno merged 1 commit into
mainfrom
claude/issue-4657-20260527-2022
May 27, 2026
Merged

Fix crash in Django admin when ScheduleItem has None speakers#4658
marcoacierno merged 1 commit into
mainfrom
claude/issue-4657-20260527-2022

Conversation

@marcoacierno
Copy link
Copy Markdown
Member

Filter out None values from the speakers property to prevent AttributeError when the admin's speakers_names method calls display_name on invalid speaker objects.

Fixes #4657

Generated with Claude Code

Filter out None values from the speakers property to prevent
AttributeError when the admin's speakers_names method calls
display_name on invalid speaker objects.

Fixes #4657

Co-authored-by: Marco Acierno <marcoacierno@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pycon Error Error May 27, 2026 8:31pm

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 27, 2026

Filters None values out of ScheduleItem.speakers to prevent an AttributeError in the admin's speakers_names display when a KeynoteSpeaker has no linked user account. The one-liner is correct, but there are several issues worth addressing.


No regression test

There is no test for the fixed bug. KeynoteSpeaker.user is the only nullable source (null=True, blank=True); a minimal test on ScheduleItem.speakers verifying None not in speakers when a keynote speaker has no user would prevent this from regressing silently.


N+1 queries in the admin list view

ScheduleItemAdmin.get_queryset() prefetches rooms but nothing needed by speakers_names(). For a list of N items, calling obj.speakers triggers roughly 5 extra queries per row (submission + speaker, keynote + keynote.speakers, additional_speakers).

# admin.py – extend get_queryset
.prefetch_related(
    "rooms",
    "submission__speaker",
    "keynote__speakers__user",
    Prefetch(
        "additional_speakers",
        queryset=ScheduleItemAdditionalSpeaker.objects.select_related("user"),
    ),
)

invitation_link crashes when submission is None

backend/schedule/admin.py:529:

def invitation_link(self, obj: ScheduleItem) -> str:
    return f"https://pycon.it/schedule/invitation/{obj.submission.hashid}"

For keynote/custom/panel items where submission is None, this raises AttributeError on the change form. Related to the same None-safety theme.


export_attendees bypasses conference-scoped queryset

backend/schedule/admin.py:425–436:

schedule_item = ScheduleItem.objects.get(id=object_id)

This is an unscoped global lookup. A staff user with access to only one conference could pass an object_id from another conference and retrieve its attendee list. Use self.get_object(request, object_id) instead, which goes through the scoped get_queryset.


Minor: speakers_names missing @admin.display decorator

Other list methods (rooms_list, attendees_count) have @admin.display(description="..."). speakers_names does not, so the column header is auto-generated from the method name rather than human-defined.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.52%. Comparing base (4147485) to head (f0a63d5).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4658   +/-   ##
=======================================
  Coverage   92.52%   92.52%           
=======================================
  Files         359      359           
  Lines       10791    10791           
  Branches      821      821           
=======================================
  Hits         9984     9984           
  Misses        696      696           
  Partials      111      111           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@marcoacierno marcoacierno merged commit 5be0ac3 into main May 27, 2026
7 of 8 checks passed
@marcoacierno marcoacierno deleted the claude/issue-4657-20260527-2022 branch May 27, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid speaker objects crash django admin

1 participant