Learn how to customize Django admin with Unfold using custom branding, navigation, filters, tabs, actions, dashboards, components, forms, and custom pages.
Django admin is a powerful starting point for internal tools and back-office applications, but the default interface is intentionally generic. Most real projects eventually need better navigation, clearer forms, richer filters, custom actions, dashboards, branding, or completely custom admin pages.
Django Unfold extends the standard Django admin instead of replacing it. You continue using familiar concepts such as ModelAdmin, forms, permissions, URLs, and templates while adding a more modern interface and additional customization options.
This guide shows how to customize Django admin with Unfold, starting with the overall appearance and navigation and then moving into model pages, filters, actions, forms, dashboards, and custom views.
Install the package with your preferred Python package manager:
uv add django-unfold
You can also use pip or Poetry:
pip install django-unfold
poetry add django-unfold
Add Unfold before django.contrib.admin in INSTALLED_APPS:
# settings.py
INSTALLED_APPS = [
"unfold",
"django.contrib.admin",
# Other applications
]
Then inherit your admin classes from Unfold's ModelAdmin:
# admin.py
from django.contrib import admin
from unfold.admin import ModelAdmin
from .models import Product
@admin.register(Product)
class ProductAdmin(ModelAdmin):
pass
This keeps the normal Django admin registration flow while enabling Unfold styling and functionality.
For the complete setup, see the Unfold installation documentation.
Most global Unfold customization is configured through the UNFOLD dictionary in settings.py.
You can change the site title, sidebar heading, subheading, logo, icon, and other identity-related settings without overriding Django admin templates.
# settings.py
from django.templatetags.static import static
UNFOLD = {
"SITE_TITLE": "Acme admin",
"SITE_HEADER": "Acme",
"SITE_SUBHEADER": "Administration",
"SITE_SYMBOL": "settings",
"SITE_ICON": {
"light": lambda request: static("icon-light.svg"),
"dark": lambda request: static("icon-dark.svg"),
},
"SITE_LOGO": {
"light": lambda request: static("logo-light.svg"),
"dark": lambda request: static("logo-dark.svg"),
},
}
This is usually enough to make the admin feel like part of your own product instead of a separate Django interface.
Unfold can also configure favicons, site links, login-page behavior, environment labels, and other site-level options.
See the Unfold settings documentation for all available values.
Unfold includes light and dark themes and allows the overall visual system to be adjusted from settings.
For example, you can force a specific theme:
UNFOLD = {
"THEME": "dark",
}
When THEME is not forced, users can switch between the available appearance modes from the interface.
You can also customize the primary and base color palettes, border radius, and font colors through the COLORS and BORDER_RADIUS settings.
UNFOLD = {
"BORDER_RADIUS": "6px",
}
For a complete color palette configuration, use the values documented in Unfold settings.
If you need deeper styling changes, Unfold also supports project-level CSS and Tailwind customization, which we will cover later in this guide.
Navigation is one of the biggest differences between the default Django admin and a more complete internal tool.
Unfold lets you define your own sidebar structure instead of relying only on Django's automatically generated application list.
# settings.py
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
UNFOLD = {
"SIDEBAR": {
"show_search": True,
"show_all_applications": False,
"navigation": [
{
"title": _("Navigation"),
"separator": True,
"collapsible": False,
"items": [
{
"title": _("Dashboard"),
"icon": "dashboard",
"link": reverse_lazy("admin:index"),
},
{
"title": _("Products"),
"icon": "inventory_2",
"link": reverse_lazy(
"admin:shop_product_changelist"
),
},
{
"title": _("Orders"),
"icon": "shopping_cart",
"link": reverse_lazy(
"admin:shop_order_changelist"
),
},
],
},
],
},
}
Navigation groups can be collapsible and can contain icons, permissions, badges, custom HTML attributes, and links to registered models or custom admin pages.
This makes it possible to organize the sidebar around workflows instead of exposing Django applications exactly as they are structured in code.
Sidebar items can display dynamic badges.
For example, you might show the number of pending orders next to the Orders navigation item.
UNFOLD = {
"SIDEBAR": {
"navigation": [
{
"title": "Sales",
"items": [
{
"title": "Orders",
"icon": "shopping_cart",
"link": reverse_lazy(
"admin:shop_order_changelist"
),
"badge": "shop.admin.pending_orders_badge",
"badge_variant": "warning",
},
],
},
],
},
}
The callback can return a value calculated from your application:
# admin.py
from .models import Order
def pending_orders_badge(request):
return Order.objects.filter(status="pending").count()
Badges are useful for queues, approvals, failed jobs, unread items, or anything else administrators need to notice quickly.
Unfold still uses Django's familiar ModelAdmin API, so standard options such as list_display, search_fields, ordering, and list_per_page continue to work.
@admin.register(Product)
class ProductAdmin(ModelAdmin):
list_display = [
"name",
"category",
"price",
"is_active",
"created_at",
]
search_fields = ["name", "sku"]
ordering = ["-created_at"]
list_per_page = 50
This means you can improve an existing Django admin incrementally. You do not have to rebuild your model administration classes when adopting Unfold.
The difference is that Unfold adds additional UI features on top of these native Django options.
The default Django admin filter system works well for basic choices, but more complex internal tools often need text inputs, numeric ranges, date ranges, dropdowns, or autocomplete filters.
Unfold provides these through unfold.contrib.filters.
Add the optional application:
# settings.py
INSTALLED_APPS = [
"unfold",
"unfold.contrib.filters",
"django.contrib.admin",
]
Then use one of the Unfold filter classes:
# admin.py
from django.contrib import admin
from unfold.admin import ModelAdmin
from unfold.contrib.filters.admin import FieldTextFilter
from .models import Product
@admin.register(Product)
class ProductAdmin(ModelAdmin):
list_filter_submit = True
list_filter = [
("name", FieldTextFilter),
]
list_filter_submit = True adds a submit button for filters that use input fields.
Unfold includes filter types for common cases such as:
See the Unfold filters documentation for the complete list.
Large Django admin forms can become difficult to scan when they contain many fieldsets and inlines.
Unfold adds tab navigation so related groups can be separated visually without splitting the object into multiple pages.
Tabs can be configured for changelists and change forms through the TABS setting.
# settings.py
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
UNFOLD = {
"TABS": [
{
"models": [
"shop.product",
],
"items": [
{
"title": _("Products"),
"link": reverse_lazy(
"admin:shop_product_changelist"
),
},
{
"title": _("Categories"),
"link": reverse_lazy(
"admin:shop_category_changelist"
),
},
],
},
],
}
Tabs can also be generated dynamically with a callback when the navigation depends on the current request or object.
For more details, see the documentation for changelist tabs and dynamic tabs.
Complex forms often contain fields that only make sense when another option is enabled.
Unfold supports conditional fields using Alpine.js expressions.
# admin.py
from django.contrib import admin
from unfold.admin import ModelAdmin
from .models import Customer
@admin.register(Customer)
class CustomerAdmin(ModelAdmin):
conditional_fields = {
"company_name": "is_company == true",
"company_id": "is_company == true",
}
The dependent fields are shown or hidden immediately based on the values in the form.
This is useful for:
Conditional fields help reduce visual clutter and make large Django admin forms easier to understand.
See conditional fields for more examples.
Unfold provides its own inline classes that extend Django's standard inline administration.
from unfold.admin import TabularInline
from .models import OrderItem
class OrderItemInline(TabularInline):
model = OrderItem
On top of regular Django inline behavior, Unfold supports additional capabilities such as sortable and paginated inlines.
For models with a position field, records can be reordered directly from the admin interface:
from unfold.admin import TabularInline
class ProductImageInline(TabularInline):
model = ProductImage
ordering_field = "position"
hide_ordering_field = True
The ordering field should be backed by an appropriate model field, such as a PositiveIntegerField.
Large related datasets can be divided into pages:
from unfold.admin import TabularInline
class OrderItemInline(TabularInline):
model = OrderItem
per_page = 20
This can significantly improve usability when a parent object has hundreds of related records.
See the sortable inline and paginated inline documentation for complete configuration details.
Django actions are useful for bulk operations, but important actions are often hidden inside the standard action dropdown.
Unfold extends Django actions and allows them to appear in different parts of the interface.
# admin.py
from django.contrib import admin
from django.db.models import QuerySet
from django.http import HttpRequest
from unfold.admin import ModelAdmin
from unfold.decorators import action
from .models import Product
@admin.register(Product)
class ProductAdmin(ModelAdmin):
actions_list = ["publish"]
@action(description="Publish", icon="publish")
def publish(
self,
request: HttpRequest,
queryset: QuerySet,
):
queryset.update(is_active=True)
Unfold supports several action locations:
Actions can also use icons, visual variants, custom permissions, and custom URLs.
This makes important workflows much more visible than keeping every operation in a single dropdown.
See the Unfold actions documentation for all action types.
The default Django admin homepage mainly acts as navigation. With Unfold, you can turn it into a dashboard for your application.
Create:
templates/admin/index.html
and configure a callback:
# settings.py
UNFOLD = {
"DASHBOARD_CALLBACK": "app.views.dashboard_callback",
}
The callback can pass your own application data into the template:
# views.py
from shop.models import Order, Product
def dashboard_callback(request, context):
context.update(
{
"orders_count": Order.objects.count(),
"products_count": Product.objects.count(),
}
)
return context
You can then render the values using Unfold components, charts, tables, cards, and your own templates.
For a complete implementation, read How to build a custom Django admin dashboard with Unfold.
Unfold includes a reusable component library for building custom interfaces that match the rest of the admin.
Available components include elements such as:
For example, a simple card can be rendered directly from a Django template:
{% load unfold %}
{% component "unfold/components/card.html" with title="Orders" %}
{{ orders_count }}
{% endcomponent %}
Components are useful beyond dashboards. They can also be used in custom views and other templates where you want to preserve the same design system.
See the Unfold components documentation for available components and examples.
Not every internal workflow belongs to a ModelAdmin changelist or change form.
Unfold provides UnfoldModelAdminViewMixin for creating custom pages that remain visually integrated with the admin interface.
# admin.py
from django.urls import path
from django.views.generic import TemplateView
from unfold.admin import ModelAdmin
from unfold.views import UnfoldModelAdminViewMixin
class SalesReportView(
UnfoldModelAdminViewMixin,
TemplateView,
):
title = "Sales report"
permission_required = ()
template_name = "admin/sales_report.html"
class ProductAdmin(ModelAdmin):
def get_urls(self):
custom_view = self.admin_site.admin_view(
SalesReportView.as_view(model_admin=self)
)
return super().get_urls() + [
path(
"sales-report/",
custom_view,
name="sales_report",
),
]
The page template can extend the regular Unfold admin layout and use the same components as dashboards.
Custom pages are useful for:
See the custom pages documentation for a full example.
When configuration and components are not enough, Unfold allows project-level styles and scripts to be loaded globally.
# settings.py
from django.templatetags.static import static
UNFOLD = {
"STYLES": [
lambda request: static("css/admin.css"),
],
"SCRIPTS": [
lambda request: static("js/admin.js"),
],
}
This is useful for small design adjustments or interactions that are specific to your project.
For larger UI work, Unfold can also be combined with a project-level Tailwind stylesheet so your own templates can use the same utility-based workflow as the rest of the interface.
Avoid overriding large parts of the generated admin HTML when a configuration option, component, or template block can solve the same problem more cleanly.
If your project needs multiple admin areas or custom site-level behavior, Unfold provides UnfoldAdminSite.
# sites.py
from unfold.sites import UnfoldAdminSite
class CustomAdminSite(UnfoldAdminSite):
pass
custom_admin_site = CustomAdminSite(
name="custom_admin",
)
This is useful when different groups of users need different model registries, URLs, or administration interfaces.
We cover this separately in How to create a custom Django admin site with Unfold.
The main advantage of Unfold is that these customizations remain built on top of Django admin.
You still use:
ModelAdminUnfold changes how those pieces are presented and adds tools for workflows that would otherwise require more template, CSS, and JavaScript work.
This makes it possible to start with a standard Django admin and progressively turn it into a more complete internal application.
If you want to customize the visual identity further or start from complete dashboard examples, Unfold Studio provides premium tools and examples built specifically for Unfold.
Studio is useful when you want to move faster on branding and dashboard implementation while keeping the underlying functionality in Django and Unfold.
You can also explore the Unfold live demo to see dashboards, filters, actions, forms, navigation, and other customization options working together.
Yes. Unfold builds on Django admin and uses the same ModelAdmin, models, forms, permissions, and URL architecture. Existing admin configuration can usually be migrated incrementally.
Use the UNFOLD settings to configure site titles, logos, icons, color palettes, border radius, and theme behavior. Custom CSS can also be loaded for project-specific adjustments.
Yes. Unfold provides configurable sidebar navigation with groups, icons, permissions, badges, collapsible sections, and links to model pages or custom views.
Yes. Unfold supports custom admin/index.html templates together with DASHBOARD_CALLBACK for injecting application data. Its component library can be used to build cards, charts, tables, and other dashboard elements.
Yes. Unfold provides view mixins and templates for adding custom admin pages while preserving the existing sidebar, permissions, design system, and other admin UI.
Yes. Unfold adds filter classes for text inputs, dropdowns, numeric ranges, date ranges, autocomplete fields, checkboxes, and other filtering patterns beyond Django's default filters.
Django admin customization with Unfold can range from a few branding settings to a complete internal application with custom navigation, dashboards, advanced filters, dynamic forms, actions, and dedicated admin pages.
You do not have to implement everything at once. Start by replacing the default ModelAdmin classes with Unfold, configure the site branding and navigation, and then add the features that solve real workflow problems for your users.
Because Unfold keeps Django's administration architecture underneath, your project can become significantly more customized without giving up the models, permissions, forms, and admin APIs that already make Django productive.
Django admin theme built with Tailwind CSS to bring modern look and feel to your admin interface. Already contains several built-in features for smooth developer experience.
© 2023 - 2026 Created by unfoldadmin.com. All rights reserved.