Skip to content

fix: stop Route admin change page from timing out#424

Merged
chrisdoehring merged 1 commit into
mainfrom
fix-route-admin-change-page-timeout
Jun 2, 2026
Merged

fix: stop Route admin change page from timing out#424
chrisdoehring merged 1 commit into
mainfrom
fix-route-admin-change-page-timeout

Conversation

@chrisdoehring

Copy link
Copy Markdown
Contributor

Problem

Requesting the Django admin change page for a Route (e.g. /admin/integrations/route/<id>/change/) times out in production.

Root cause

The change page renders RouteProviderInline and RouteDestinationInline. Each inline renders a <select> of every Integration — for every existing row and every extra form. Integration.__str__ is f"{self.owner.name} - {self.name} - {self.type.name}", and neither owner nor type is select_related, so building each dropdown fires N+1 queries. The total cost scales with the number of integrations, which is large in production → timeout.

Quantified with the new regression test: rendering the page went from 460 → 4,259 queries after adding just 100 integrations (~38 queries per integration).

This is distinct from the changelist COUNT(*) issue fixed in #418 — this is the single-object change view and its inlines.

Fix

Add autocomplete_fields = ("integration",) to both inlines. The FK now renders as an AJAX autocomplete box (backed by IntegrationAdmin's existing search_fields) instead of a full-table dropdown, so no Integration options are pre-rendered and there is no N+1.

Testing

  • New integrations/tests/test_admin.py renders the change page, adds 100 integrations, and asserts the query count stays flat (delta ≤ 10). Fails before the fix, passes after.
  • manage.py check passes (confirms the autocomplete_fields config is valid and won't break admin startup).

Note for reviewers

Staff users need view permission on Integration for the autocomplete results to populate (standard Django autocomplete behavior). Superusers and typical admin roles already have it.

🤖 Generated with Claude Code

The Django admin Route change page renders RouteProviderInline and
RouteDestinationInline, each of which renders a <select> of *every*
Integration for every inline row and every extra form. Integration.__str__
touches owner.name and type.name (neither select_related), so building those
dropdowns is an N+1 storm whose cost scales with the integration count -- the
cause of the change page timing out in production.

Adding autocomplete_fields = ("integration",) to both inlines replaces the
full-table dropdowns with AJAX autocomplete (backed by IntegrationAdmin's
existing search_fields), so no Integration options are pre-rendered.

A regression test renders the change page, adds 100 integrations, and asserts
the query count stays flat. Before the fix it went 460 -> 4259 queries; after,
it stays within a small constant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses production timeouts when rendering the Django admin Route change page by preventing the inlines from pre-rendering a full-table <select> of all Integration rows (which previously triggered N+1 queries via Integration.__str__).

Changes:

  • Switched RouteProviderInline and RouteDestinationInline to use autocomplete_fields = ("integration",) to avoid rendering all Integration options.
  • Added a regression test that asserts the Route change page query count does not grow materially after adding 100 Integration rows.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
cdip_admin/integrations/admin.py Uses autocomplete_fields on Route-related inlines to avoid full-table dropdown rendering and N+1 queries.
cdip_admin/integrations/tests/test_admin.py Adds a query-count regression test ensuring Route change page rendering stays flat as integrations increase.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chrisdoehring chrisdoehring merged commit af0c614 into main Jun 2, 2026
2 checks passed
@chrisdoehring chrisdoehring deleted the fix-route-admin-change-page-timeout branch June 2, 2026 00:15
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.

2 participants