Skip to main content

Add collapsible app groups to Django's built-in admin sidebar.

Project description

django-admin-collapse-apps

CI PyPI version Python versions Django versions License: MIT

Collapsible app groups for the built-in Django admin sidebar — no theme, no jQuery, no server-side state.

📖 English · Русский

django-admin-collapse-apps adds a small toggle button to each app group in Django's standard admin sidebar (and dashboard app list) so you can collapse the apps you rarely touch. It enhances the sidebar Django already ships — it does not replace it — and it stays fully usable when JavaScript is disabled.

Expanded Collapsed
Admin sidebar with every app group expanded Admin sidebar with Catalog and Orders collapsed

Features

  • Zero-config. Install the app and every eligible app group gets a collapse toggle.
  • Non-invasive. Keeps Django's sidebar structure, permissions, ordering, and search intact.
  • Remembers your choice. Collapsed state is stored in one browser cookie per user agent.
  • Progressive enhancement. Without JavaScript the sidebar stays fully expanded and usable.
  • Accessible. Real <button> controls with synced aria-expanded / aria-controls, keyboard support, and a visible focus ring.
  • Search-friendly. Sidebar search still reveals models inside collapsed groups, then your collapsed state is restored.
  • Themeable. Works with Django's light and dark admin themes; a few namespaced CSS variables let you restyle the toggle.

What it deliberately does not do

  • Does not replace the full admin sidebar template.
  • Does not add jQuery, icon fonts, CDN assets, or any frontend dependency.
  • Does not persist state on the server (one cookie only, in the MVP).
  • Does not touch admin permissions, model ordering, or your project branding.

Requirements

  • Python 3.10 – 3.14
  • Django 4.2, 5.0, 5.1, 5.2, or 6.0

Installation

python -m pip install django-admin-collapse-apps

Add the app to INSTALLED_APPS before django.contrib.admin so Django can discover the package's admin/base_site.html extension:

INSTALLED_APPS = [
    "django_admin_collapse_apps",
    "django.contrib.admin",
    # ...
]

That's it. Open any admin page and each app group in the sidebar now has a toggle. No further configuration is required.

Configuration

By default every app group is collapsible. To restrict toggles to specific apps, set ADMIN_COLLAPSE_APPS to a list of Django app labels:

ADMIN_COLLAPSE_APPS = ["auth", "orders", "catalog"]

Normalization rules:

Value Result
unset / None / [] / () all sidebar apps are collapsible
list / tuple of app labels only those apps are collapsible
a plain string like "auth" invalid — never split into characters
empty or whitespace-only entries invalid

App labels are stripped of surrounding whitespace and deduplicated (first occurrence wins). Invalid values degrade safely to the "all apps" behavior, and Django's system check framework reports the problem as django_admin_collapse_apps.E001 when you run manage.py check.

Tip: an app label is the segment in the admin URL — /admin/auth/user/ belongs to the auth app, /admin/support/ticket/ to the support app. Use app labels, not verbose names or import paths.

If you list an app label that is not installed, Django's system check reports it as a warning (django_admin_collapse_apps.W001) — the entry simply never matches a sidebar group.

Multiple admin sites on one domain

Collapsed state is stored in a single cookie named django_admin_collapsed_apps. If you run more than one admin instance on the same domain (for example under different path prefixes) and want each to keep independent state, set a cookie namespace:

ADMIN_COLLAPSE_APPS_COOKIE_NAMESPACE = "backoffice"

The cookie is then named django_admin_collapsed_apps_backoffice. The namespace must be a short token of ASCII letters, digits, hyphen, or underscore (1–64 characters); an invalid value is reported as django_admin_collapse_apps.W002 and safely falls back to the default cookie name.

How it works

  1. The setting is normalized once on the server into a small JSON payload ({mode, allApps, appLabels}) rendered into a <script type="application/json"> element by the package's admin/base_site.html.
  2. A vanilla-JS runtime reads that payload and scopes itself to Django's standard app-list containers only: #nav-sidebar on model pages and #content-main on the dashboard (detected via the dashboard body class, so it works on Django 4.2 through 6.0). On any other page it exits quietly.
  3. It inserts one accessible toggle per eligible group, restores collapsed state from the django_admin_collapsed_apps cookie, and keeps that cookie in sync as you collapse and expand groups.

The cookie stores only comma-separated app labels, uses SameSite=Lax (and adds Secure on HTTPS), and is deleted entirely once nothing is collapsed.

Customizing the toggle

The stylesheet exposes namespaced CSS variables. Override them in your own admin CSS (loaded after the package stylesheet):

:root {
    --django-admin-collapse-apps-toggle-color: currentColor;
    --django-admin-collapse-apps-toggle-expanded-symbol: "▾";
    --django-admin-collapse-apps-toggle-collapsed-symbol: "▸";
    --django-admin-collapse-apps-toggle-focus-ring: currentColor;
    --django-admin-collapse-apps-toggle-focus-ring-width: 2px;
    --django-admin-collapse-apps-toggle-focus-ring-offset: 2px;
    --django-admin-collapse-apps-toggle-float: right;
    --django-admin-collapse-apps-toggle-margin-inline-start: 0.5rem;
    --django-admin-collapse-apps-toggle-margin-inline-end: 0;
}

For example, to use ASCII symbols or move the toggle before the app name:

:root {
    --django-admin-collapse-apps-toggle-expanded-symbol: "v";
    --django-admin-collapse-apps-toggle-collapsed-symbol: ">";
    --django-admin-collapse-apps-toggle-float: left;
    --django-admin-collapse-apps-toggle-margin-inline-start: 0;
    --django-admin-collapse-apps-toggle-margin-inline-end: 0.35rem;
}

The stylesheet is scoped to #nav-sidebar, body.dashboard #content-main, and package-owned classes, and it honors prefers-reduced-motion and forced-colors.

Custom admin/base_site.html

If your project already overrides admin/base_site.html and preserves Django's extrahead/extrastyle blocks with {{ block.super }}, the package assets are still discovered automatically. If your template fully owns those blocks, load the assets explicitly:

{% extends "admin/base_site.html" %}
{% load django_admin_collapse_apps %}

{% block extrahead %}
{{ block.super }}
{% collapse_apps_assets %}
{% endblock %}

collapse_apps_assets renders the stylesheet, the JSON config, and the script together. The lower-level tags collapse_apps_stylesheet, collapse_apps_config_script, and collapse_apps_javascript are available when you need finer placement. Don't copy Django's full sidebar template just to enable this package.

Third-party admin themes

This package enhances Django's built-in admin sidebar; it does not replace it. Whether it works with a third-party theme depends on how that theme renders navigation:

  • Themes that keep the stock sidebar markup (a #nav-sidebar nav with app-<label> groups, and/or a body.dashboard #content-main app list) work as-is — for example projects that only restyle the standard admin with CSS.
  • Themes that replace the sidebar with their own navigation component (e.g. Jazzmin, django-admin-interface's custom nav, Grappelli, Unfold) render a different DOM, so the runtime finds no eligible groups and exits quietly. It will not break the theme, but it also has nothing to collapse. Those themes usually ship their own menu-collapsing feature — use that instead.

If a theme only overrides admin/base_site.html, keep Django's extrahead/extrastyle blocks (or load the assets explicitly as shown above) and the standard sidebar continues to work. The runtime is idempotent and scoped to package-owned DOM hooks, so it is safe to leave enabled even when a page has no collapsible groups.

Troubleshooting

Toggles do not appear

Make sure django_admin_collapse_apps is listed before django.contrib.admin in INSTALLED_APPS. The package provides its admin templates and static assets through that ordering.

I use a custom admin/base_site.html

Keep {{ block.super }} in both the extrahead and extrastyle blocks, or load the assets explicitly with {% collapse_apps_assets %} (see Custom admin/base_site.html).

Static files are missing in production

Run python manage.py collectstatic and confirm your static-files setup serves django_admin_collapse_apps/css/collapse_apps.css and django_admin_collapse_apps/js/collapse_apps.js. python manage.py findstatic django_admin_collapse_apps/js/collapse_apps.js should print a path.

The aria-label / tooltip text is in English

The toggle's accessible label and tooltip are currently English-only ("Expand …" / "Collapse …"); the visible control is a language-neutral symbol. Full localization is planned for a future release.

Demo project

The repository ships a small demo project (catalog, orders, support, reports, plus the standard auth app) for manual validation and screenshots:

python demo/manage.py migrate --run-syncdb
python demo/bootstrap_demo.py
python demo/manage.py runserver

Sign in at http://127.0.0.1:8000/admin/ with admin / admin. The default mode (demo_project.settings.all_apps) makes every app collapsible; demo_project.settings.selected_apps restricts toggles to catalog and orders.

Development

python -m pip install -e ".[quality]"
python -m ruff check .        # lint
npm run check:js              # JavaScript syntax check (Node's --check)
python -m pytest              # test suite (self-configures Django; no plugin)
python -m build               # build wheel + sdist

The test suite is behavior-focused: configuration normalization, template-tag rendering, end-to-end admin integration, the demo project, packaging metadata, and a small set of static-asset guards.

AI integration guides

Wiring this package in with an AI coding agent? Point it at docs/ai/ — concise, English-only integration/presentation/runtime guides written for AI tooling.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_admin_collapse_apps-0.1.1.tar.gz (152.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_admin_collapse_apps-0.1.1-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file django_admin_collapse_apps-0.1.1.tar.gz.

File metadata

File hashes

Hashes for django_admin_collapse_apps-0.1.1.tar.gz
Algorithm Hash digest
SHA256 867fc9fc31d46e2321133256f84130e60dc5cfabae7972dee213dd2807c6bd59
MD5 a480d59662becef5e6421916b8724e26
BLAKE2b-256 dd60fccf51d82190556269b689e20ab0ce052d09fabfb2aab4a3ac5ffaf51bf0

See more details on using hashes here.

File details

Details for the file django_admin_collapse_apps-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_admin_collapse_apps-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 35ceb93a8ebb454eda048b670bdd53788cb3e3adcdab5d16c936e2c8cb0ea0d9
MD5 ff2010196fd871c069f7e4ae4cdb832a
BLAKE2b-256 ae4246681bb6543eb524933ebfeae291b160607ed02e26ef063963647ae1219a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page