django-subadmin-unfold
django-subadmin-unfold makes
django-subadmin's nested model
admins feel at home in Django Unfold, from
navigation and breadcrumbs to custom actions.
Installation
pip install django-subadmin-unfold
The package requires Python 3.12+, Django 5.2+, django-subadmin 5.2+, and django-unfold 0.102+. It has been tested with Django 5.2, 6.0, and 6.1. Add the apps in this order so the adapter's templates are used:
# settings.py
INSTALLED_APPS = [
"subadmin_unfold",
"unfold",
"subadmin",
"django.contrib.admin",
# Django's other contrib apps and your own apps...
]
Using it
Start with the django-subadmin example.
The model relationships are the same. Use UnfoldSubAdmin for nested admins
and UnfoldRootSubAdmin for the registered parent admin:
from django.contrib import admin
from subadmin_unfold.admin import UnfoldRootSubAdmin, UnfoldSubAdmin
from .models import Child, Parent
class ChildAdmin(UnfoldSubAdmin):
model = Child
@admin.register(Parent)
class ParentAdmin(UnfoldRootSubAdmin):
subadmins = (ChildAdmin,)
The nested list and change pages use Unfold's templates and breadcrumbs.
Grouping subadmin links
Django admin has no subadmin links, and django-subadmin displays each link separately. This adapter lets you group links into dropdowns, following Unfold's dropdown actions pattern. Here Children stays as a direct link, while Notes and Documents sit under Related:
subadmins = (
ChildAdmin,
{
"title": "Related",
"icon": "folder",
"items": (NoteAdmin, DocumentAdmin),
},
)
NoteAdmin and DocumentAdmin are defined like ChildAdmin. Groups work on
root and nested admins. A group with no permitted links is hidden; one
permitted link still appears in a dropdown.
Icons
Set subadmin_icon on a nested admin to give its link a
Material Symbols icon:
class ChildAdmin(UnfoldSubAdmin):
model = Child
subadmin_icon = "groups"
The default link icon is view_list. To change it for all subadmins, set
SUBADMIN_UNFOLD_DEFAULT_ICON in your Django settings:
SUBADMIN_UNFOLD_DEFAULT_ICON = "list_alt"
A class's subadmin_icon takes precedence over this setting. Both work for
direct links and links inside groups. Set a dropdown's icon with the group's
icon key, as above.
Datasets
Unfold datasets display
a changelist inside a change form. Regular BaseDataset works on subadmin
pages. Use SubAdminDataset when the dataset's rows should link to a direct
child subadmin's change pages.
The following setup shows Children on a Parent change form. It replaces the
short admin.py example above. ChildAdmin provides the full nested pages,
ChildDatasetAdmin configures and filters the embedded table, and
ChildDataset points table rows to those nested pages:
from django.contrib import admin
from django.contrib.admin.utils import unquote
from subadmin_unfold.admin import UnfoldRootSubAdmin, UnfoldSubAdmin
from subadmin_unfold.datasets import SubAdminDataset
from unfold.admin import ModelAdmin
from .models import Child, Parent
class ChildAdmin(UnfoldSubAdmin):
model = Child
class ChildDatasetAdmin(ModelAdmin):
list_display = ("name",)
def get_queryset(self, request):
queryset = super().get_queryset(request)
parent_id = (self.extra_context or {}).get("object")
if not parent_id or not self.has_view_or_change_permission(request):
return queryset.none()
return queryset.filter(parent_id=unquote(parent_id))
class ChildDataset(SubAdminDataset):
model = Child
model_admin = ChildDatasetAdmin
@admin.register(Parent)
class ParentAdmin(UnfoldRootSubAdmin):
subadmins = (ChildAdmin,)
change_form_datasets = (ChildDataset,)
ChildDatasetAdmin is a separate, unregistered admin used by Unfold to render
the table. Its queryset must enforce parent scope and any child visibility
rules. SubAdminDataset only changes row links; it does not create detail pages
or inherit settings from ChildAdmin.
Unfold actions
Define Unfold actions on
UnfoldSubAdmin as you would on an Unfold ModelAdmin. List, detail, row, and
submit-line actions are supported. For example, a list action can use
request.subadmin to access the current parent:
from django.http import HttpResponse
from unfold.decorators import action
class ChildAdmin(UnfoldSubAdmin):
model = Child
actions_list = ("show_parent",)
@action(description="Show parent", icon="account_tree")
def show_parent(self, request):
return HttpResponse(request.subadmin.parent_instance.name)
The adapter includes the parent IDs in nested action URLs. Nested admins can
also define get_custom_urls(); those views receive model_admin and
request.subadmin. Reverse a nested custom URL with
model_admin.reverse_url(name, *parent_ids, *custom_args).
Metadata
Release files for django-subadmin-unfold 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_subadmin_unfold-1.0.0.tar.gz | 13.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_subadmin_unfold-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.8 kB
Release files / django_subadmin_unfold-1.0.0.tar.gz
| Download URL | django_subadmin_unfold-1.0.0.tar.gz |
|---|---|
| Size | 13.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
326641a899f7f9c900d2246536d3e82032d8ad5ede0d34d8ff7584702e0de8e5
|
|
BLAKE2b-256 checksum How to use checksums |
f8e1fd895685c7c2ce780166f6ed8bd0b1c40c7bcf178b3926ef0e0544c7eba2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / django_subadmin_unfold-1.0.0-py3-none-any.whl
| Download URL | django_subadmin_unfold-1.0.0-py3-none-any.whl |
|---|---|
| Size | 15.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
053c69662428a6f4d8bd65f85219599f1ffbb56334cccbbd0136b19bc8e1b502
|
|
BLAKE2b-256 checksum How to use checksums |
0243a188f0bd317aeef4401d6a7d5dbd8106077ecbb901e093920389c3d332d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency log