Convert the Admin UI sidebar to use the action framework.
Review Request #14721 — Created Dec. 2, 2025 and updated
The admin sidebar used to be composed based off of an HTML file
populated using state from a template tag, with template hooks to append
custom HTML to the sections. While there was some degree of
extensibility, it was a bit limited, requiring the consumer to generate
just the right HTML.This change converts the sidebar to use actions instead. There's now an
action group per group in the sidebar, and an action per child.
Specialized sidebar action renderers take care of rendering with
existing support for the template hook points.The Manage section has the most specializations. The group renderer
takes care of looking up the counts and Add Item URLs for each child
action, caching the results for quicker lookup. The item renderer then
provides this to a template, based on the cached state (falling back to
direct querying if not in the cache).With this, extensions can now simply register actions in the Admin UI
sidebar, taking advantage of the built-in rendering and capabilities.
Tested all the links in the admin UI.
Tested fallback Manage item logic when the cache results come up empty.
| Summary | ID |
|---|---|
| 61244c3196e612e5e86f2e9ea69d602810c30082 |
| Description | From | Last Updated |
|---|---|---|
|
Can we add tests for some of the new behavior? get_default_admin_actions() get_default_admin_attachment_points() Item counts/urls. |
|
|
|
Shouldn't this inherit from BaseAdminSidebarGroupAction |
|
|
|
Shouldn't this inherit from BaseAdminSidebarGroupAction |
|
|
|
This ends up creating the queryset object when the class is defined, which seems like it might create confusing bugs … |
|
|
|
This should be typed to return Iterator[ActionAttachmentPoint] |
|
-
-
Can we add tests for some of the new behavior?
get_default_admin_actions()get_default_admin_attachment_points()- Item counts/urls.
-
-
-
This ends up creating the queryset object when the class is defined, which seems like it might create confusing bugs (especially in the case of running tests). I feel like this would be much better done as a property that can be reimplemented in subclasses and return a new QuerySet when needed.
-